For Development HEAD DRAFTSearch (procedure/syntax/module):

12.21 data.range - Range

Module: data.range

A range object is an immutable sequence with O(1) indexed access to the elements, and each element may be computed procedurally. For example, a range of intergers between 0 and N can be trivially realized as a range, where i-th element is simply computed by identity. It is a lot more space-efficient than actually generating a sequence containing every number.

It also allows certain operations efficient, such as taking subsequence or appending sequences.

A range object can be used with :range qualifier in the SRFI-42 eager comprehension (see srfi.42 - Eager comprehensions).

A portable range object interface is defined in srfi.196. We implement the range object as a <sequence>, so that all sequence framework interface can be used on the ranges (see gauche.sequence - Sequence framework). We also provide some additional procedures that are not in SRFI-196.

Classes

Class: <range>

Range object class. Internally we use several subclasses according to the nature of the range, but externally all ranges can be treated as an instance of <range>.

Class: <range-meta>

The metaclass of <range> class.

Constructors

Function: range length indexer

[SRFI-196]{data.range} Creates and returns a range of length length, whose i-th element (0 <= i < length)) is determined by a procedure indexer, which takes i as the sole argument and returns the corresponding element.

Note that indexer must run in O(1) time, and must be referentially transparent. The impelemntation may “expand” the range, that is, computes the element values into a flat vector internally.

(range->list (range 5 (^i (+ i 10))))
 ⇒ (10 11 12 13 14)
Function: numeric-range start end :optional step

[SRFI-196]{data.range} Creates and returns a range of numbers starting from start (inclusive) and ending below end (exclusive), increasing with step. The default value of step is 1.

(range->list (numeric-range 2 6))
 ⇒ (2 3 4 5)

(range->list (numeric-range 0 5 2/3))
 ⇒ (0 2/3 4/3 2 8/3 10/3 4 14/3)
Function: iota-range length :optional start step

[SRFI-196]{data.range} Creates and returns a range of numbers. Total length of the range is length. The range starts from start (default 0), and increased with step (default 1).

(range->list (iota-range 5))
  ⇒ (0 1 2 3 4)

(range->list (iota-range 7 1 -1/7))
  ⇒ (1 6/7 5/7 4/7 3/7 2/7 1/7)
Function: vector-range vec :optional start end

[SRFI-196+]{data.range} Returns a range over the given vector vec. The vector is kept in the range, so you shouldn’t mutate vec. See also vector->range below.

The optional start and end arguments limits the range of the vector to be used. They are Gauche’s extension and not in SRFI-196.

(range->list (vector-range '#(a b c)))
  ⇒ (a b c)

(range->list (vector-range '#(a b c d e) 1 4))
  ⇒ (b c d)

(range-ref (vector-range '#(a b c d e) 2) 0)n
  ⇒ c
Function: uvector-range uvec :optional start end

{data.range} Returns a range over the given uniform vector uvec. The uniform vector is kept in the range, so you shouldn’t mutate uvec.

The optional start and end arguments limits the range of the uniorm vector to be used.

Function: bitvector/bool-range bvec :optional start end
Function: bitvector/int-range bvec :optional start end

{data.range} Returns a range over the given bitvector bvec. Bitvector/bool-range regards bvec as a boolean vector, while bitvector/int-range regards it as a vector of 0 and 1. See Bitvectors, for the details of bitvectors. Note that bvec is kept in the range, so you shouldn’t mutate uvec.

The optional start and end arguments limits the range of the uniorm vector to be used.

Function: string-range str :optional start end

[SRFI-196]{data.range} Returns a range over each character in the given string str. The string is kept in the range, so you shouldn’t mutate str.

The optional start and end arguments limits the range of the vector to be used. They are Gauche’s extension and not in SRFI-196.

(range->list (string-range "abc"))
  ⇒ (#\a #\b #\c)

(range->list (string-range "abcde" 1 4))
  ⇒ (#\b #\c #\d)
Function: range-append range …

[SRFI-196]{data.range} Returns a new range that walks over concatenation of the given ranges.

Function: range-reverse range :optional start end

[SRFI-196+]{data.range} Returns a new range that walks over the elements of range, but in reverse order.

The optional start and end arguments limits the range of the vector to be used. They are Gauche’s extension and not in SRFI-196.

(range->list (range-reverse (string-range "abc")))
  ⇒ (#\c #\b #\a)

(range->list (range-reverse (string-range "abcdef" 1 4)))
  ⇒ (#\d #\c #\b)

Predicates

Function: range? obj

[SRFI-196]{data.range} Returns true iff obj is a range.

Function: range=? elt= range …

[SRFI-196]{data.range} Returns true iff all ranges have the same length, and any pair of corresponding elements in the given ranges are equal in terms of elt= predicate.

As edge cases, when zero or one range is given, #t is returned.

(range=? eqv? (numeric-range 0 5)
              (iota-range 5)
              (vector-range '#(0 1 2 3 4)))
  ⇒ #t

Accessors

Function: range-length range

[SRFI-196]{data.range} Returns the length of range.

Function: range-ref range i :optional fallback

[SRFI-196+]{data.range} Returns the i-th element of range. The index i must be an exact integer.

If i is negative, or greater than or equal to the length of range, fallback is returned if given, or an error is signaled. The fallback argument is Gauche’s extension and not in SRFI-196.

Function: range-first range :optional fallback

[SRFI-196+]{data.range} Returns the first element of range.

If the range is empty, fallback is returned if given, or an error is signaled. The fallback argument is Gauche’s extension and not in SRFI-196.

Function: range-last range :optional fallback

[SRFI-196+]{data.range} Returns the last element of range.

If the range is empty, fallback is returned if given, or an error is signaled. The fallback argument is Gauche’s extension and not in SRFI-196.

Iteration

Function: range-split-at range k

[SRFI-196]{data.range} Returns two ranges, the first one with elements before k-th elements of range, and the second one with k-th elements and after of range.

Function: subrange range start end

[SRFI-196]{data.range} Returns a new range that contains start-th (inclusive) to end-th (exclusive) elements of range.

Function: range-segment range len

[SRFI-196]{data.range} Split range into subranges of length len. The last range may be shorter than len.

(map range->list (range-segment (numeric-range 0 11) 4))
 ⇒ ((0 1 2 3) (4 5 6 7) (8 9 10))
Function: range-take range count
Function: range-take-right range count

[SRFI-196]{data.range} Returns a new range containing initial count elements or last count elements from range, respectively

Function: range-drop range count
Function: range-drop-range range count

[SRFI-196]{data.range} Returns a new range containing elements of range except initial count elements or last count elements, respectively.

Function: range-count pred range range2 …

[SRFI-196]{data.range} A procedure pred must take as many arguments as the given ranges. It is called on each corresponding element of range, range2 …, and the procedure returns the number of times pred returned true.

If more than one ranges are given and not all ranges are of the same length, iteration terminates at the end of the shortest range.

Function: range-any pred range range2 …

[SRFI-196]{data.range} A procedure pred must take as many arguments as the given ranges. It is called on each first element of range, range2 …, then each second element, and so on. As soon as pred returns a true value, the iteration stops and the value pred returns becomes the result of range-any. If pred never returns a true value, #f is returned.

If more than one ranges are given and not all ranges are of the same length, iteration terminates at the end of the shortest range.

Function: range-every pred range range2 …

[SRFI-196]{data.range} A procedure pred must take as many arguments as the given ranges. It is called on each first element of range, range2 …, then each second element, and so on. As soon as pred returns a false value, the iteration stops and range-any returns #f. If all pred returns a true value, the last value is returned.

If more than one ranges are given and not all ranges are of the same length, iteration terminates at the end of the shortest range.

Function: range-map proc range range2 …
Function: range-map->list proc range range2 …
Function: range-map->vector proc range range2 …

[SRFI-196]{data.range} Mapping over ranges. A procedure proc must take as many arguments as the given ranges, and is called on each corresponding element of range, range2 …. The results are collected and returned as a range (range-map), a list (range-map->list, or a vector (range-map->vector. The dynamic order of in which proc is invoked is not specified. Note that range-map computes all elements before returning the result range.

If more than one ranges are given and not all ranges are of the same length, iteration terminates at the end of the shortest range.

Function: range-for-each proc range range2 …

[SRFI-196]{data.range} A procedure proc must take as many arguments as the given ranges. It is invoked with the first elements of each range, and then with the second elements of them, and so on, until the shortest range is exhausted. The result of proc is discarded.

Returns an undefined value.

Function: range-filter pred range
Function: range-filter->list pred range
Function: range-remove pred range
Function: range-remove->list pred range
Function: range-filter-map pred range range2 …
Function: range-filter-map->list pred range range2 …

[SRFI-196]{data.range} A procedure pred must take as many arguments as the given ranges. These are range version of filter, remove, and filter-map (see Walking over lists).

The procedures without ->list returns the result as a range, while the ones with ->list returns the result as a list.

The iteration stops when the shortest range is exhausted. The result is eagerly computed.

(range->list (range-filter odd? (iota-range 10)))
  ⇒ (1 3 5 7 9)
(range-remove->list odd? (iota-range 10))
  ⇒ (0 2 4 6 8)
(range->list (range-filter-map (every-pred odd? square) (iota-range 10)))
  ⇒ (1 9 25 49 81)
Function: range-fold kons knil range range2 …
Function: range-fold-right kons knil range range2 …

[SRFI-196]{data.range} These are range version of fold and fold-right (see Walking over lists). The iteration stops when the shortest range is exhausted.

Searching

Function: range-index pred range range2 …
Function: range-index-right pred range range2 …

[SRFI-196]{data.range} Returns the first or the last index of the element in the input range that satisfies a predicate pred. If there are more than one ranges, pred must take as many arguments as the number of input ranges, and applied on each corresponding elements of the input range.

(range-index > (vector-range '#(1 5 3 2 4))
               (vector-range '#(4 3 0 4 6)))
  ⇒ 1
(range-index-right > (vector-range '#(1 5 3 2 4))
                     (vector-range '#(4 3 0 4 6)))
  ⇒ 2
Function: range-take-while pred range
Function: range-take-while-right pred range
Function: range-drop-while pred range
Function: range-drop-while-right pred range

[SRFI-196]{data.range} Same as take-while, take-while-right, drop-while, and drop-while-right, except those operate on an range and return an range, instead of a list (see scheme.list - R7RS lists).

Conversion

Function: range->list range
Function: range->vector range
Function: range->string range

[SRFI-196]{data.range} Convert a range to a list, a vector ro a string, respectively. For range->string, the argument must be a range consists solely of characters.

Function: vector->range vec :optional start end

[SRFI-196]{data.range} Returns a range whose elements are those of a vector vec. Unlike vector-range, the content of vec is copied into the range, so mutating vec won’t alter the resulting range.

The optional start and end arguments limit the portion to be used for the result.

Function: range->generator range :optional start end

[SRFI-196]{data.range} Returns a generator that yields each element of range, between start (inclusive) and end (exclusive) indexes. When omitted, start is 0 and end is the size of the range.



For Development HEAD DRAFTSearch (procedure/syntax/module):
DRAFT