Package name |
RANGE-OBJECT |
1. Package documentation
A range object implementation for Common Lisp.
documentation | |
sourcecode |
A range object is an immutable sequence-like object whose values are retrievable using an algorithm. This library is based closely on SRFI 196, an implementation of range objects in Scheme, created by John Cowan and Wolfgang Corcoran-Mathe.
See below for the API. The following sections give an overview of the provided functions.
1.1. Constructors
make-range
is the basic constructor, taking a length and an indexer
function. The indexer is the algorithmic representation of the range: it
maps an integer in [0,length) to the required range value.
Specialist constructors are available to construct ranges from numbers or
existing sequences: these include numeric-range
, iota-range
,
string-range
and vector-range
.
Two further functions construct new ranges from existing ranges:
range-append
and range-reverse
.
Conversion to-from sequences is supported with range-to-list
,
range-to-string
, range-to-vector
, string-to-range
and vector-to-range
.
For example:
* (range-to-list (range-append (iota-range 10) (numeric-range 10 20))) (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19)
1.2. Accessor
range-elt
provides direct access to each element in the range.
* (range-elt (vector-range #(3 9 1)) 1) 9
range-subseq
returns a new range over a subrange; it takes arguments
the same as subseq
on sequences.
* (range-to-list (range-subseq (numeric-range 10 50) 5 10)) (15 16 17 18 19)
The following functions in this subsection are taken from SRFI 196 and
separate ranges into smaller ranges. The most basic is range-split-at
,
which separates a range at a given index point into two ranges, returned as
two values.
* (multiple-value-bind (ra rb) (range-object:range-split-at (range-object:iota-range 10) 3) (range-object:range-to-list ra)) (0 1 2)
range-segment
instead creates a list of ranges, each of a required length:
* (length (range-segment (iota-range 18 10) 5)) 4 * (range-to-list (fourth (range-segment (iota-range 18 10) 5))) (25 26 27)
The group of drop/take functions either take a count or, in the
drop-while/take-while form, a predicate to find a point to split the range.
All accept a :from-end
keyword to support operating from the right.
* (range-to-list (range-drop (numeric-range 0 10) 5)) (5 6 7 8 9) * (range-to-list (range-drop (numeric-range 0 10) 5 :from-end t)) (0 1 2 3 4) * (range-to-list (range-take-while #'(lambda (x) (< x 10)) (numeric-range 5 15))) (5 6 7 8 9)
1.3. Sequence-Like Iteration
A number of functions are provided analogous to those available on general sequences. These accept the same keywords and have similar semantics.
These include the conditionals range-every
range-some
range-notany
range-notevery
which all take a predicate and one or more ranges or
sequences. Range elements are accessed using range-elt
and sequence
elements using elt
. Results and behaviour are the same as with the
sequence function equivalents.
For example:
* (range-some #'evenp (numeric-range 0 10)) T * (range-notevery #'< (vector-range #(1 2 3)) (vector-range #(3 3 3))) T
For iteration, analogues of count
find
and position
are provided, along
with their higher-order variants: these are range-count
range-find
range-position
with the usual keyword arguments :start
:end
:from-end
:key
:test
.
For example:
* (range-count-if #'evenp (numeric-range 0 10) :end 5) 3
In addition range-reduce
works like reduce
for sequences, supporting the standard
:start
:end
:test
:initial-value
:key
keyword options.
* (range-reduce #'+ (numeric-range 0 10)) 45
dorange
and range-mapc
support direct iteration over the items in a
range. e.g. to print the items in a range:
(dorange (i (numeric-range 20 30)) (print i))
1.4. Unimplemented Functions
Some functions in SRFI 196 or from Lisp’s sequences are not supported. These
include mutation functions and those where the SRFI implementation results in an
internal representation being a vector. Hence, no map
equivalent, except
for range-mapc
, which is equivalent to Scheme’s for-each.
1.5. Install
To install range-object
, download the
latest release
and make the code available to the
asdf
system; on quicklisp or similar, place the code in "quicklisp/local-projects".
This package has no dependencies.
1.6. MIT Licence
Copyright © 2024 Peter Lane
Copyright © 2020 Wolfgang Corcoran-Mathe - SRFI 196 Scheme implementation
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2. Functions
- Lambda list
-
iota-range ( len &optional (start 0) (step 1) )
- Documentation
-
Returns a range-object instance with numeric elements.
- Lambda list
-
make-range ( len indexer )
- Documentation
-
Returns a range-object instance with given algorithmic representation.
- Lambda list
-
numeric-range ( start end &optional (step 1) )
- Documentation
-
Returns a range-object instance with numeric elements.
- Lambda list
-
range-append ( range-a range-b )
- Documentation
-
Returns a new range-object instance based on following items in the first range followed by the second.
- Lambda list
-
range-count ( item range &key from-end start end key test test-not )
- Documentation
-
Returns count of item in given range bounded by start and end satisfying given test.
- Lambda list
-
range-count-if ( pred range &key from-end start end key )
- Documentation
-
Returns count of items satisfying predicate within given bounds.
- Lambda list
-
range-count-if-not ( pred range &key from-end start end key )
- Documentation
-
Returns count of items not satisfying predicate within given bounds.
- Lambda list
-
range-drop ( range n &key from-end )
- Documentation
-
Returns a new range containing all but the first/last n items of range.
- Lambda list
-
range-drop-while ( pred range &key from-end )
- Documentation
-
Returns a range which omits leading/trailing elements of range that satisfy pred, up to the first one that does not.
- Lambda list
-
range-elt ( range index )
- Documentation
-
Return item at given index of range.
- Lambda list
-
range-equalp ( range-a range-b &key (test #'eql) )
- Documentation
-
Two ranges are equal if their elements are equal.
- Lambda list
-
range-every ( pred range-1 &rest ranges )
- Documentation
-
Return t if given predicate returns t for all elements across ranges.
- Lambda list
-
range-find ( item range &key from-end test test-not start end key )
- Documentation
-
Returns item in range which satisfies test with provided item within given bounds.
- Lambda list
-
range-find-if ( pred range &key from-end start end key )
- Documentation
-
Returns item in range which satisfies given predicate within given bounds.
- Lambda list
-
range-find-if-not ( pred range &key from-end start end key )
- Documentation
-
Returns item in range which does not satisfy given predicate within given bounds.
- Lambda list
-
range-first ( range )
- Documentation
-
Return first item in range.
- Lambda list
-
range-last ( range )
- Documentation
-
Return last item in range.
- Lambda list
-
range-length ( range )
- Documentation
-
Returns the length of the given range.
- Lambda list
-
range-mapc ( op range )
- Documentation
-
Applies given operation to each item in the range in turn.
- Lambda list
-
range-notany ( pred range-1 &rest ranges )
- Documentation
-
Return t if given predicate returns nil for all elements across ranges.
- Lambda list
-
range-notevery ( pred range-1 &rest ranges )
- Documentation
-
Return t if given predicate returns nil for at least one element across ranges.
- Lambda list
-
range-position ( item range &key from-end test test-not start end key )
- Documentation
-
Returns index in range which satisfies test with provided item within given bounds.
- Lambda list
-
range-position-if ( pred range &key from-end start end key )
- Documentation
-
Returns index in range which satisfies given predicate within given bounds.
- Lambda list
-
range-position-if-not ( pred range &key from-end start end key )
- Documentation
-
Returns index in range which does not satisfy given predicate within given bounds.
- Lambda list
-
range-reduce ( op r &key start end from-end key (initial-value 'range-reduce-undeclared) )
- Documentation
-
Reduce for ranges.
- Lambda list
-
range-reverse ( range )
- Documentation
-
Returns a new range object instance whose values are the same as range but indexed in reverse.
- Lambda list
-
range-segment ( range len )
- Documentation
-
Returns a list of subranges of range, each of length len.
- Lambda list
-
range-some ( pred range-1 &rest ranges )
- Documentation
-
Return t if given predicate returns t for at least one element across ranges.
- Lambda list
-
range-split-at ( range index )
- Documentation
-
Returns as values two ranges, one < index and one >= index.
- Lambda list
-
range-subseq ( range start &optional end )
- Documentation
-
Returns a new range which is a subsequence of the given range.
- Lambda list
-
range-take ( range n &key from-end )
- Documentation
-
Returns a new range containing only the first/last n items of range.
- Lambda list
-
range-take-while ( pred range &key from-end )
- Documentation
-
Returns a range which contains leading/trailing elements of range that satisfy pred, up to the first one that does not.
- Lambda list
-
range-to-list ( range )
- Documentation
-
Returns a list from the given range.
- Lambda list
-
range-to-string ( range )
- Documentation
-
Returns a string from the given range.
- Lambda list
-
range-to-vector ( range )
- Documentation
-
Returns a vector from the given range.
- Lambda list
-
rangep ( range )
- Documentation
-
Return t if given object is a range object.
- Lambda list
-
string-range ( str )
- Documentation
-
Returns a range-object instance with elements across given string.
- Lambda list
-
string-to-range ( str )
- Documentation
-
Returns a range object from the given string.
- Lambda list
-
vector-range ( vec )
- Documentation
-
Returns a range-object instance with elements across given vector.
- Lambda list
-
vector-to-range ( vec )
- Documentation
-
Returns a range object from the given vector.
3. Macros
- Lambda list
-
dorange ( (var range &optional result) &body body )
- Documentation
-
Sets var to each value in range in turn before executing body. Returns result or nil.