For Gauche 0.9.9


Previous: , Up: Library modules - R7RS standard libraries   [Contents][Index]

10.3 R7RS large

R7RS large is still under development, and we’re gradually adding support of the libraries that has been passed.

Currently R7RS-large has two editions (Red and Tangerine). Among the libraries in those editions, the following are not supported yet:

scheme.ilist      scheme.rlist        scheme.text
scheme.bytevector scheme.show

The following are supported libraries:


Next: , Previous: , Up: R7RS large   [Contents][Index]

10.3.1 scheme.list - R7RS lists

Module: scheme.list

This module is a rich collection of list manipulation procedures, and same as srfi-1.

Note that Gauche supports quite a few scheme.list procedures as built-in. The following procedures can be used without loading scheme.list module. For the manual entries of these procedures, Pairs and lists.

null-list? cons* last member
take drop take-right drop-right take! drop-right!
delete delete! delete-duplicates delete-duplicates!
assoc alist-copy alist-delete alist-delete!
any every filter filter! fold fold-right find find-tail
split-at split-at! iota

List constructors

Function: xcons cd ca

[R7RS list] {scheme.list} Equivalent to (cons ca cd). Useful to pass to higher-order procedures.

Function: list-tabulate n init-proc

[R7RS list] {scheme.list} Constructs an n-element list, in which each element is generated by (init-proc i).

(list-tabulate 4 values) ⇒ (0 1 2 3)
Function: circular-list elt1 elt2 …

[R7RS list] {scheme.list} Constructs a circular list of the elements.

(circular-list 'z 'q) ⇒ (z q z q z q …)

List predicates

Function: not-pair? x

[R7RS list] {scheme.list} Same as (lambda (x) (not (pair? x))).

SRFI-1 says: Provided as a procedure as it can be useful as the termination condition for list-processing procedures that wish to handle all finite lists, both proper and dotted.

Function: list= elt= list …

[R7RS list] {scheme.list} Determines list equality by comparing every n-th element of given lists by the procedure elt=.

It is an error to apply list= to anything except proper lists.

The equality procedure must be consistent with eq?, i.e.

(eq? x y) ⇒ (elt= x y).

List selectors

Function: first pair
Function: second pair
Function: third pair
Function: fourth pair
Function: fifth pair
Function: sixth pair
Function: seventh pair
Function: eighth pair
Function: ninth pair
Function: tenth pair

[R7RS list] {scheme.list} Returns n-th element of the (maybe improper) list.

Function: car+cdr pair

[R7RS list] {scheme.list} Returns two values, (car pair) and (cdr pair).

List miscellaneous routines

Function: zip clist1 clist2 …

[R7RS list] {scheme.list} Equivalent to (map list clist1 clist2 …). If zip is passed n lists, it returns a list as long as the shortest of these lists, each element of which is an n-element list comprised of the corresponding elements from the parameter lists.

(zip '(one two three)
     '(1 2 3)
     '(odd even odd even odd even odd even))
     ⇒ ((one 1 odd) (two 2 even) (three 3 odd))

(zip '(1 2 3)) ⇒ ((1) (2) (3))

At least one of the argument lists must be finite:

(zip '(3 1 4 1) (circular-list #f #t))
     ⇒ ((3 #f) (1 #t) (4 #f) (1 #t))
Function: unzip1 list
Function: unzip2 list
Function: unzip3 list
Function: unzip4 list
Function: unzip5 list

[R7RS list] {scheme.list} unzip1 takes a list of lists, where every list must contain at least one element, and returns a list containing the initial element of each such list. unzip2 takes a list of lists, where every list must contain at least two elements, and returns two values: a list of the first elements, and a list of the second elements. unzip3 does the same for the first three elements of the lists, and so on.

(unzip2 '((1 one) (2 two) (3 three))) ⇒
   (1 2 3) and
   (one two three)

List fold, unfold & map

Function: pair-fold kons knil clist1 clist2 …
Function: pair-fold-right kons knil clist1 clist2 …

[R7RS list] {scheme.list} Like fold and fold-right, but the procedure kons gets each cdr of the given clists, instead of car.

(pair-fold cons '() '(a b c d e))
  ⇒ ((e) (d e) (c d e) (b c d e) (a b c d e))

(pair-fold-right cons '() '(a b c d e))
  ⇒ ((a b c d e) (b c d e) (c d e) (d e) (e))
Function: unfold p f g seed :optional tail-gen

[R7RS list] {scheme.list} Fundamental recursive list constructor. Defined by the following recursion.

(unfold p f g seed tail-gen) ≡
   (if (p seed)
       (tail-gen seed)
       (cons (f seed)
             (unfold p f g (g seed))))

That is, p determines where to stop, g is used to generate successive seed value from the current seed value, and f is used to map each seed value to a list element.

(unfold (pa$ = 53) integer->char (pa$ + 1) 48)
  ⇒ (#\0 #\1 #\2 #\3 #\4)
Function: unfold-right p f g seed :optional tail

[R7RS list] {scheme.list} Fundamental iterative list constructor. Defined by the following recursion.

(unfold-right p f g seed tail) ≡
  (let lp ((seed seed) (lis tail))
    (if (p seed)
        lis
        (lp (g seed) (cons (f seed) lis))))
(unfold-right (pa$ = 53) integer->char (pa$ + 1) 48)
 ⇒ (#\4 #\3 #\2 #\1 #\0)
Function: map! f clist1 clist2 …

[R7RS list] {scheme.list} The procedure f is applied to each element of clist1 and corresponding elements of clist2s, and the result is collected to a list. Cells in clist1 is reused to construct the result list.

Function: map-in-order f clist1 clist2 …

[R7RS list] {scheme.list} A variant of map, but it guarantees to apply f on each elements of arguments in a left-to-right order. Since Gauche’s map implementation follows the same order, this function is just a synonym of map.

Function: pair-for-each f clist1 clist2 …

[R7RS list] {scheme.list} Like for-each, but the procedure f is applied on clists themselves first, then each cdrs of them, and so on.

(pair-for-each write '(a b c))
 ⇒ prints (a b c)(b c)(c)

List partitioning

Function: partition pred list
Function: partition! pred list

[R7RS list] {scheme.list} filter and remove simultaneously, i.e. returns two lists, the first is the result of filtering elements of list by pred, and the second is the result of removing elements of list by pred.

(partition odd? '(3 1 4 5 9 2 6))
  ⇒ (3 1 5 9) (4 2 6)

partition! is the linear-update variant. It may destructively modifies list to produce the result.

List searching

Function: take-while pred clist
Function: take-while! pred list

[R7RS list] {scheme.list} Returns the longest initial prefix of clist whose elements all satisfy pred.

Function: drop-while pred clist

[R7RS list] {scheme.list} Drops the longest initial prefix of clist whose elements all satisfy pred, and returns the rest.

Function: span pred clist
Function: span! pred list
Function: break pred clist
Function: break! pred list

[R7RS list] {scheme.list} span is equivalent to (values (take-while pred clist) (drop-while pred clist)). break inverts the sense of pred.

Function: list-index pred clist1 clist2 …

[R7RS list] {scheme.list} Returns the index of the leftmost element that satisfies pred. If no element satisfies pred, #f is returned.

Association lists

Function: alist-cons key datum alist

[R7RS list] {scheme.list} Returns (cons (cons key datum) alist). This is an alias of the Gauche builtin procedure acons.

Lists as sets

These procedures use a list as a set, that is, the elements in a list matter, but their order doesn’t.

All procedures in this category takes a comparison procedure elt=, as the first argument, which is used to determine two elements in the given sets are the same.

Since lists require linear time to search, those procedures aren’t suitable to deal with large sets. See R7RS sets, if you know your sets will contain more than a dozen items or so.

See also Combination library, which concerns combinations of elements in the set.

Function: lset<= elt= list1 …

[R7RS list] {scheme.list} Returns #t iff all elements in list1 are also included in list2, and so on. If no lists are given, or a single list is given, #t is returned.

Function: lset= elt= list1 list2 …

[R7RS list] {scheme.list} Returns #t if all elements in list1 are in list2, and all elements in list2 are in list1, and so on.

(lset= eq? '(b e a) '(a e b) '(e e b a)) ⇒ #t
Function: lset-adjoin elt= list elt …

[R7RS list] {scheme.list} Adds elt … to the set list, if each one is not already a member of list. (The order doesn’t matter).

(lset-adjoin eq? '(a b c) 'a 'e) ⇒ '(e a b c)
Function: lset-union elt= list1 …

[R7RS list] {scheme.list} Returns the union of the sets list1 ….

Function: lset-intersection elt= list1 list2 …

[R7RS list] {scheme.list} Returns a set of elements that are in every lists.

Function: lset-difference elt= list1 list2 …

[R7RS list] {scheme.list} Returns a set of elements that are in list1 but not in list2. In n-ary case, binary difference operation is simply folded.

Function: lset-xor elt= list1 …

[R7RS list] {scheme.list} Returns the exclusive-or of given sets; that is, the returned set consists of the elements that are in either list1 or list2, but not in both. In n-ary case, binary xor operation is simply folded.

Function: lset-diff+intersection elt= list1 list2 …

[R7RS list] {scheme.list} Returns two sets, a difference and an intersection of given sets.

Function: lset-union! elt= list …
Function: lset-intersection! elt= list1 list2 …
Function: lset-difference! elt= list1 list2 …
Function: lset-xor! elt= list1 …
Function: lset-diff+intersection! elt= list1 list2 …

[R7RS list] {scheme.list} Linear update variant of the corresponding procedures. The cells in the first list argument may be reused to construct the result.


Next: , Previous: , Up: R7RS large   [Contents][Index]

10.3.2 scheme.vector - R7RS vectors

Module: scheme.vector

This module adds rich set of vector operations to the built-in / R7RS vector procedures.

The following procedures are built-in. See Vectors, for the description. We only explain the procedures that are not built-in.

make-vector          vector               vector?
vector-ref           vector-set!          vector-length
vector-fill!         vector-copy          vector-copy!
vector-append        vector->list         list->vector
reverse-list->vector vector->string       string->vector
vector-map           vector-map!          vector-for-each

This module is srfi-133, which supersedes srfi-43 (see Vector library (Legacy)). Note that the interface of following procedures in srfi-43 are changed for the consistency:

vector-map           vector-map!          vector-for-each
vector-fold          vector-fold-right    vector-count

Some of the functionalities of srfi-43 version is supported by built-in procedures (e.g. Built-in vector-map-with-index is the same as srfi-43’s vector-map). So there’s little point for new code to use srfi-43.

Vector constructors

Function: vector-unfold f length seed …

[R7RS vector] {scheme.vector} Creates a vector of length length, filling elements left to right by calling f repeatedly.

The procedure f must take as many arguments as one plus number of seed values, and must return the same number of values. The first argument is the index. The first return value is used for the element of the result vector, and the rest of return values are passed to the next call of f.

(vector-unfold (^[i] (* i i)) 5)
 ⇒ #(0 1 4 9 16)

(vector-unfold (^[i x] (values (cons i x) (* x 2))) 8 1)
 ⇒ #((0 . 1) (1 . 2) (2 . 4) (3 . 8)
    (4 . 16) (5 . 32) (6 . 64) (7 . 128))
Function: vector-unfold-right f length seed …

[R7RS vector] {scheme.vector} Creates a vector of length length, filling elements right to left by calling f repeatedly.

The procedure f must take as many arguments as one plus number of seed values, and must return the same number of values. The first argument is the index. The first return value is used for the element of the result vector, and the rest of return values are passed to the next call of f.

(vector-unfold-right (^[i] (* i i)) 5)
 ⇒ #(0 1 4 9 16)

(vector-unfold-right (^[i x] (values (cons i x) (* x 2))) 8 1)
 ⇒ #((0 . 128) (1 . 64) (2 . 32) (3 . 16)
    (4 . 8) (5 . 4) (6 . 2) (7 . 1))
Function: vector-reverse-copy vec :optional start end

[R7RS vector] {scheme.vector} Copies the vector vec with reversing its elements. Optional start and end arguments can limit the range of the input.

(vector-reverse-copy '#(a b c d e) 1 4)
 ⇒ #(d c b)
Function: vector-concatenate list-of-vectors

[R7RS vector] {scheme.vector} Same as (apply vector-append list-of-vectors).

Function: vector-append-subvectors spec …

[R7RS vector] {scheme.vector} The number of arguments must be multiple of 3. The argument list must be in the following format, where each vecN is a vector, and startN and endN are nonnegative integers:

vec1 start1 end1 vec2 start2 end2 …

This procedure creates a new vector by concatenating subvectors specified by each triplet. That is, it works as if it’s the following code, except it avoids copying each subvector:

(vector-append (vector-copy vec1 start1 end1)
               (vector-copy vec2 start2 end2)
               …)

Here’s an example:

(vector-append-subvectors '#(a b c d e) 0 3
                          '#(f g h i j) 2 5)
  ⇒ #(a b c h i j)

Vector predicates

Function: vector-empty? vec

[R7RS vector] {scheme.vector} Returns #t if vec’s length is zero, and #f if vec’s length is more than zero. Signals an error if vec is not a vector.

Function: vector= elt= vec …

[R7RS vector] {scheme.vector} Compares vecs element-wise, using given predicate elt=. Returns #t iff lengths of all the vectors are the same, and every corresponding elements are equal by elt=. Elt= is always called with two arguments and must return #t iff two are the same.

Vector iteration

Function: vector-fold kons knil vec1 vec2 …

[R7RS vector] {scheme.vector} Kons is a procedure that takes n+1 arguments, where n is the number of given vectors. For each element of the given vectors, kons is called as (kons seed e_1i e_2i …), where and e_ni is the i-th element of the vector n. If the lengths of the vectors differ, iteration stops when the shortest vector is exhausted.

The initial value of seed is knil, and the return value from kons is used as the next seed value. The last return value of kons is returned from vector-fold.

The iteration is strictly left to right.

Note that the seed value precedes elements, which is opposite to fold (see Mapping over collection). It’s an unfortunate historical glitch; vector-fold-left would be more consistent name.

(vector-fold (^[a b] (cons b a)) '() '#(a b c d))
  ⇒ (d c b a)
Function: vector-fold-right kons knil vec1 vec2 …

[R7RS vector] {scheme.vector} Like vector-fold, but elements in the vec1 vec2 … are visited from right to left.

Unlike fold-right (see Mapping over sequences), the procedure kons takes the accumulated value in the first argument.

(vector-fold-right (^[a b] (cons b a)) '() '#(a b c d))
  ⇒ (a b c d)
Function: vector-count pred vec1 vec2 …

[R7RS vector] {scheme.vector} Applies pred on each elements in argument vectors (if N vectors are given, pred takes N arguments, the first being i-th element of vec1, the second being i-th element of vec2, etc.) Then returns the number of times pred returned true value. The order pred applied to each element is unspecified.

(vector-count odd? '#(0 1 2 3 4)
  ⇒ 2

(vector-count < '#(7 3 9 1 5) '#(6 8 2 3 8 8))
  ⇒ 3
Function: vector-cumulate f seed vec

[R7RS vector] {scheme.vector} Returns a fresh vector with the same size of vec, with the elements calculated as follows:

The first element of result vector is a result of procedure f called with seed and the first element of vec.

The i-th element of result vector is a result of procedure f called with i-1-th element of result vector and i-th element of vec.

(vector-cumulate string-append "z" '#("a" "b" "c"))
  ⇒ #("za" "zab" "zabc")

Vector searching

Function: vector-index pred vec1 vec2 …
Function: vector-index-right pred vec1 vec2 …

[R7RS vector] {scheme.vector} Returns the index of the first or the last elements in vec1 vec2 … that satisfy pred, respectively. Returns #f if no elements satisfy pred. In vector-index, comparison ends at the end of the shortest vector. For vector-index-right, all the vectors must have the same length.

Function: vector-skip pred vec1 vec2 …
Function: vector-skip-right pred vec1 vec2 …

[R7RS vector] {scheme.vector} Like vector-index and vector-index-right, except that the result of pred is negated. That is, returns the index of the first or the last elements that don’t satisfy pred.

Function: vector-binary-search vec value cmp :optional start end

[R7RS+] {scheme.vector} Look for value in a sorted vector vec, and returns its index if it is found, or #f if it is not found.

Comparison of value and an element in vec is done by a procedure cmp, which takes two arguments, and should return a negative integer if the first argument is less than the second, 0 if they are the same, and a positive integer if the first is greater than the second.

Elements in vec must be ordered from smaller to greater w.r.t. cmp. Using that fact, this procedure performs binary search instead of linear search.

The optional arguments start and end are an extension to SRFI-133, and can be used to limit the range of the search in start-th element (inclusive) to end-th element (exclusive).

Function: vector-any pred vec1 vec2 …

[R7RS vector] {scheme.vector} Applies pred on each corresponding elements of vec1 vec2 … left to right, and as soon as pred returns non-#f value, the procedure stops iteration and returns the value.

If no elements that satisfy pred are found, it returns #f.

Vectors can have different lengths. Iteration stops at the end of the shortest.

Function: vector-every pred vec1 vec2 …

[R7RS vector] {scheme.vector} Applies pred on each corresponding elements of vec1 vec2 … left to right. If all the elements (when the lengths of vectors differ, the first N elements where N is the length of the shortest) satisfy pred, returns the last result of pred. If any of the elements don’t satisfy pred, it returns #f immediately without looking further.

(vector-every < '#(1 2 3 4 5) '#(2 3 4 4 5)
  ⇒ #f

(vector-every (^[x y] (and (real? x) (real? y) (- x y)))
              '#(1 2 3)
              '#(2 4 6))
  ⇒ -3
Function: vector-partition pred vec

[R7RS vector] {scheme.vector} Allocates a fresh vector of the same size as vec, then fill it with elements in vec that satisfy pred, followed by elements that don’t satisfy pred.

Returns two values, the newly created vector and an exact integer of the index of the first element that doesn’t satisfy pred in the returned vector.

(vector-partition odd? '#(1 2 3 4 5 6 7 8))
  ⇒ #(1 3 5 7 2 4 6 8) and 4

Vector mutators

Function: vector-swap! vec i j

[R7RS vector] {scheme.vector} Swaps vector vec’s i-th and j-th elements. Returns unspecified value.

(rlet1 v (vector 'a 'b 'c 'd 'e)
  (vector-swap! v 0 2))
  ⇒ #(c b a d e)
Function: vector-reverse! vec :optional start end

[R7RS vector] {scheme.vector} Reverse the elements of vec. Returns an undefined value. Optional start and end arguments can limit the range of operation.

(rlet1 v (vector 'a 'b 'c 'd 'e)
  (vector-reverse! v 0 4))
  ⇒ #(d c b a e)
Function: vector-reverse-copy! target tstart source :optional sstart send

[R7RS vector] {scheme.vector} Like vector-copy!, but reverses the order of elements from start.

(rlet1 v (vector 'a 'b 'c 'd 'e)
  (vector-reverse-copy! v 2 '#(1 2)))
  ⇒ #(a b 2 1 e)

It is ok to pass the same vector to target and source; it always works even if the regions of source and destination are overlapping.

(rlet1 v (vector 'a 'b 'c 'd 'e)
  (vector-reverse-copy! v 1 v 1))
  ⇒ #(a e d c b)
Function: vector-unfold! f rvec start end seeds …
Function: vector-unfold-right! f rvec start end seeds …

[R7RS vector] {scheme.vector} Fill rvec starting from index start (inclusive) and ending at index end (exclusive), with the elements calculated by f.

The procedure f takes the number of seed values seeds … plus one arguments. The first argument is the current index, followed by seed values. The same number of values as the arguments must be returned from f; the first return value is used to fill the current element of rvec, and the rest of the values are used as the next seed values.

The result vector is filled from left to right by vector-unfold!, and right to left by vector-unfold-right!. The return value is unspecified.

(let1 rvec (vector 'a 'b 'c 'd 'e 'f)
  (vector-unfold! (^[i] (+ i 1)) rvec 1 4)
  rvec)
 ⇒ #(a 2 3 4 e f)

(let1 rvec (vector 'a 'b 'c 'd 'e 'f)
  (vector-unfold-right! (^[i] (+ i 1)) rvec 1 4)
  rvec)
 ⇒ #(a 2 3 4 e f)

(let1 rvec (vector 'a 'b 'c 'd 'e 'f)
  (vector-unfold! (^[i x] (values x (* x 2))) rvec 1 5 10)
  rvec)
 ⇒ #(a 10 20 40 80 f)

(let1 rvec (vector 'a 'b 'c 'd 'e 'f)
  (vector-unfold! (^[i x] (values x (* x 2))) rvec 1 5 10)
  rvec)
 ⇒ #(a 80 40 20 10 f)

Vector conversion

Function: reverse-vector->list vec :optional start end

[R7RS vector] {scheme.vector} Same as (reverse (vector->list vec start end)), but more efficient.


Next: , Previous: , Up: R7RS large   [Contents][Index]

10.3.3 scheme.vector.@ - R7RS uniform vectors

Module: scheme.vector.@

@ is actually one of u8, s8, u16, s16, u32, s32, u64, s64, f32, f64, c64 or c128. (Gauche’s gauche.uvector module also provides f16 and c32 vectors.)

These modules provides vectors that can hold specific range of numeric values. In Gauche we use packed representation, meaning numbers are tightly stored in consecutive memory region.

Additionally, scheme.vector.base module exports basic procedures, make-@vector, @vector, @vector?, @vector-length, @vector-ref, @vector-set!, @vector->list, list->@vector, @?, for @ being over all element types.

The gauche.uvector module is a superset of these modules, and all procedures are described there. See Uniform vectors for the details.


Next: , Previous: , Up: R7RS large   [Contents][Index]

10.3.4 scheme.sort - R7RS sort

Module: scheme.sort

Provides utilities to sort, and to work on sorted lists/vectors. This module is the same as srfi-132.

Gauche has built-in sort and merge procedures (see Sorting and merging). This module has a bit different API. Notably, the ordering predicate comes first than the sequence to be sorted, and the procedures dealing with vectors uniformly support start/end arguments

This module also provide useful procedures working on sorted or partially sorted sequences.

Function: list-sort elt< lis
Function: list-sort! elt< lis
Function: list-stable-sort elt< lis
Function: list-stable-sort! elt< lis

[R7RS sort] {scheme.sort} Sort elements in a list lis according to the ordering predicate elt<, which takes two elements from lis and returns true iff the first argument is strictly less than the second argument.

Returns a sorted list. The procedures with bang are linear update version. They are allowed, but not required, to reuse lis. The “stable” variation guarantees stable sort.

These are basically the same as Gauche’s built-in sort, sort!, stable-sort and stable-sort!, except the Gauche’s version works on any sequences and takes arguments differently. (See Sorting and merging.)

Function: list-sorted? elt< lis

[R7RS sort] {scheme.sort} Returns true if the list list is sorted according to the ordering predicate elt<.

See also sorted? in Sorting and merging.

Function: list-merge elt< lis1 lis2
Function: list-merge! elt< lis1 lis2

[R7RS sort] {scheme.sort} Given two sorted lists lis1 and lis2, returns a new sorted list according to the ordering predicate elt<.

Note that list-merge! works in-place, that is, all the pairs in lis1 and lis2 are reused.

See also merge and merge! in Sorting and merging.

Function: vector-sort elt< vec :optional start end
Function: vector-stable-sort elt< vec :optional start end

[R7RS sort] {scheme.sort} Sort elements in a vector vec according to the ordering predicate elt<, which takes two elements from vec and returns true iff the first argument is strictly less than the second argument. Returns a fresh sorted vector. The “stable” variation guarantees stable sort.

When the optional start and/or end arguments are given, only the portion from start (inclusive) and end (exclusive) of vec are looked at. The result vector’s length is end - start). When end is omitted, the length of vec is assumed.

See also sort and stable-sort in Sorting and merging.

Function: vector-sort! elt< vec :optional start end
Function: vector-stable-sort! elt< vec :optional start end

[R7RS sort] {scheme.sort} Sort elements “in-place” in a vector vec according to the ordering predicate elt<, which takes two elements from vec and returns true iff the first argument is strictly less than the second argument. Upon successful return, vec’s elements are sorted. Returns unspecified value; the caller must rely on the side effect.

When the optional start and/or end arguments are given, only the portion from start (inclusive) and end (exclusive) of vec are sorted; other elements will remain intact. When end is omitted, the length of vec is assumed.

See also sort! and stable-sort! in Sorting and merging.

Function: vector-sorted? elt< vec :optional start end

[R7RS sort] {scheme.sort} Returns true iff vec between start (inclusive) and end (exclusive) is sorted according to the ordering predicate elt<. If start and/or end is/are omitted, 0 and the length of vec are assumed, respectively.

See also sorted? in Sorting and merging.

Function: vector-merge elt< vec1 vec2 :optional start1 end1 start2 end2
Function: vector-merge! elt< rvec vec1 vec2 :optional rstart start1 end1 start2 end2

[R7RS sort] {scheme.sort} Merge two sorted vectors vec1 and vec2 into one vector, according to the ordering predicate elt<.

The optional argument start1 and end1 restricts vec1’s portion to be looked at, and start2 and end2 restricts vec2’s portion to be looked at.

The functional version vector-merge allocates a fresh vector to hold the result, and returns it.

The side-effecting version vector-merge! uses rvec. to hold the result. The procedure doesn’t return a meaningful value. The optional rstart argument specifies the index of rvec from which the result is filled; the default is 0.

Function: list-delete-neighbor-dups elt= lis
Function: list-delete-neighbor-dups! elt= lis
Function: vector-delete-neighbor-dups elt= vec :optional start end
Function: vector-delete-neighbor-dups! elt= vec :optional start end

[R7RS sort] {scheme.sort} From the given list lis or vector vec, these procedures delete adjacent duplicate elements. Equivalence is checked by elt= procedure.

(list-delete-neighbor-dups eq? '(m i s s i s s i p p i))
  ⇒ (m i s i s i p i)

The non-destructive versions list-delete-neighbor-dups and vector-delete-neighbor-dups returns a freshly allocated list and vector, respectively.

The destructive list-delete-neighbor-dups! works in-place, reusing pairs of lis. No allocation will be done.

The destructive vector-delete-neighbor-dups! has a bit different interface. It updates vec in-place, but since we can’t change the length of the vector, it gathers the result from the beginning of the vec, then returns the next index newend of vec—that is, after calling this procedure, [start, newend) holds the result. The elements between [newend, end) will remain intact.

The optional start and end arguments limits the region of vec to be looked at.

(vector-delete-neighbor-dups eq? '#(a a a b b c c d d e e f f) 3 10)
  ⇒ #(b c d e)

(let1 v '#(a a a b b c c d d e e f f)
  (cons (vector-delete-neighbor-dups! eq? v 3 10) v))
  ⇒ (7 . #(a a a b c d e d d e e f f))

Note: The gauche.sequence module provides neighbor duplicate deletion on generic sequences. Those procedures are implemented by the generic versions as shown below. See Other operations over sequences, for the details.

list-delete-neighbor-dups

delete-neighbor-dups

list-delete-neighbor-dups!

delete-neighbor-dups-squeeze!

vector-delete-neighbor-dups

delete-neighbor-dups

vector-delete-neighbor-dups!

delete-neighbor-dups!

Function: vector-select! elt< vec k :optional start end

[R7RS sort] {scheme.sort} Select k-th smallest element in vec according to the ordering predicate elt<. K is zero based, i.e. 0 means the smallest. The optional start and end arguments limits the range of vec to be looked at, and defaulted to 0 and the length of vec, respectively. K must satisfy start <= k < end.

This procedure runs in O(n) time, and requires no extra stroage. This procedure may partially modify vec.

Function: vector-separate! elt< vec k :optional start end

[R7RS sort] {scheme.sort} Find k-th smallerst element in vec (pivot) between between start and end, according to the ordering predicate elt<, then rearrange elements between start and end so that elements smaller than the pivot comes between start and start + k, and the rest of the elements come afterwards. When omitted, start is 0 and end is the length of the vec.

This can be used as a building block for in-place divide-and-conquer algorithms. Runs in O(n) time.

Function: vector-find-median elt< vec knil :optional mean
Function: vector-find-median! elt< vec knil :optional mean

[R7RS sort] {scheme.sort} Find median value of elements in vec, when ordered by the ordering predicate elt<. Non-destructive version vector-find-median runs in O(n) time. The destructive version vector-find-median! is specified to leave vec sorted, so it runs in O(n log n).

  1. If vec is empty, knil is returned. This is the only case knil is used.
  2. If vec has odd number of elements, the element falls in the exactly the midpoint when ordered, is returned.
  3. If vec has even number of elements, the two elements closest to the midpoint is chosen and passed to the procedure mean, and its result is returned. The default of mean is an arithmetic mean of numbers.
(vector-find-median < #() 0)
  ⇒ 0

(vector-find-median < #(78 61 19 38 51) 0)
  ⇒ 51

(vector-find-median < #(78 61 19 38 51 52) 0)
  ⇒ 103/2

Next: , Previous: , Up: R7RS large   [Contents][Index]

10.3.5 scheme.set - R7RS sets

Module: scheme.set

Sets and bags are unordered collection of Scheme values. A set doesn’t count duplicates; if you add an item which is already in a set, you still have one item of the kind. A bag counts duplicates; if you add an item which is already in a bag, you have two items of the kind.

To check whether the items are “the same”, sets and bags takes a comparator at construction time. The comparator doesn’t need to have an ordering predicate (we don’t need to order the elements) but has to have a hash function. See Basic comparators, for the details of comparators.

This module is originally specified as srfi-113, and then incorporated to R7RS large.

As a Gauche’s extension, sets and bags implement collection protocol (see Collection framework, for the details), and generic collection operations can be applied.

(coerce-to <list> (set eq-comparator 'a 'b 'a 'b))
  ⇒ (a b)      ; order may differ

(coerce-to <list> (bag eq-comparator 'a 'b 'a 'b))
  ⇒ (a a b b)  ; order may differ

Constructors

Function: set comparator elt …
Function: bag comparator elt …

[R7RS set] {scheme.set} Creates a new set and bag from given elements elt …. Given comparator will be used to compare equality of elements.

(set->list (set eq-comparator 'a 'b 'a 'b))
  ⇒ (a b)

(bag->list (bag eq-comparator 'a 'b 'a 'b))
  ⇒ (a a b b)
Function: set-unfold stop? mapper successor seed comparator
Function: bag-unfold stop? mapper successor seed comparator

[R7RS set] {scheme.set} Procedurally creates a set or a bag. The first three arguments, stop?, mapper and successor, are all procedures that takes one argument, the current seed value. It may be easier to know their types:

seed      :: Seed
stop?     :: Seed -> Boolean
mapper    :: Seed -> ElementType
successor :: Seed -> Seed

The stop? procedure takes the current seed value and returns a boolean value - if it is true, iteration stops.

The mapper procedure takes the current seed value and returns an item, which is to be included in the resulting set or bag.

The successor procedure takes the current seed value and returns the next seed value.

And the seed argument gives the initial seed value.

(set->list (set-unfold (^s (= s 75))
                       integer->char
                       (^s (+ s 1))
                       65
                       eqv-comparator))
 ⇒ (#\D #\H #\A #\E #\I #\J #\B #\F #\C #\G)

Predicates

Function: set-contains? set obj
Function: bag-contains? bag obj

[R7RS set] {scheme.set} Check if obj is in the set or the bag.

Function: set-empty? set
Function: bag-empty? bag

[R7RS set] {scheme.set} Returns #t iff the given set or bag is empty.

Function: set-disjoint? set1 set2
Function: bag-disjoint? bag1 bag2

[R7RS set] {scheme.set} Returns #t iff the given arguments (sets or bags) don’t have common items. Both arguments must have the same comparator—otherwise an error is signaled.

Accessors

Function: set-member set obj default
Function: bag-member bag obj default

[R7RS set] {scheme.set} Returns an element in the given set or bag which is equal to obj in terms of the set’s or the bag’s comparator. If no such element is found, default will be returned.

Note that the returned object doesn’t need to be “the same” as obj in a usual sense. See the following example:

(let s (set string-ci-comparator "abc" def")
  (set-member s "ABC" #f))
  ⇒ "abc"
Function: set-element-comparator set
Function: bag-element-comparator bag

[R7RS set] {scheme.set} Returns the comparator used to compare the elements for the set or the bag.

Updaters

Function: set-adjoin set elt …
Function: bag-adjoin bag elt …

[R7RS set] {scheme.set} Returns a newly created set or bag that contains all the elements in the original set/bag, plus given elements. The new set/bag’s comparator is the same as the original set/bag’s one.

Function: set-replace set elt
Function: bag-replace bag elt

[R7RS set] {scheme.set} Returns a newly created set/bag with the same comparator with the original set/bag, and the same elements, except that the elements equal to elt (in terms of set/bag’s comparator) is replaced by elt. If the original set/bag doesn’t contain an element equal to elt, the original one is returned.

(let ((s (set string-ci-comparator "ABC" "def")))
  (set->list (set-replace s "abc")))
  ⇒ ("abc" "def")
Function: set-delete set elt …
Function: bag-delete bag elt …

[R7RS set] {scheme.set} Returns a newly created set or bag that has the same comparator and the same elements in the original set/bag, except that the item which is equal to elt.

Function: set-delete-all set elt-list
Function: bag-delete-all bag elt-list

[R7RS set] {scheme.set} Returns a newly created set or bag with the same comparator of the original set/bag, with the elements of the original set/bag except the ones listed in elt-list.

Function: set-adjoin! set elt …
Function: bag-adjoin! bag elt …
Function: set-replace! set elt
Function: bag-replace! bag elt
Function: set-delete! set elt …
Function: bag-delete! bag elt …
Function: set-delete-all! set elt-list
Function: bag-delete-all! bag elt-list

[R7RS set] {scheme.set} These are the linear update versions of their counterparts. It works just like the ones without !, except that the original set/bag may be reused to produce the result, instead of new one being allocated.

Note that it’s not guaranteed that the original set/bag is modified, so you should use the return value of them, instead of relying on the side effects.

Function: set-search! set elt failure success
Function: bag-search! bag elt failure success

[R7RS set] {scheme.set} Lookup-and-modify procedures. The failure and success arguments are procedures.

First, they search elt in the given set/bag. If an item that matches elt is found, the success procedure is called with three arguments, as follows:

(success item update remove)

The update argument is a procedure that takes two arguments, as (update new-item retval). It replaces the matching item in the set/bag with new-item, and returns retval. The remove argument is a procedure that takes one argument, as (remove retval). It removes the matching item in the set/bag, and returns retval.

If an item that matches elt is not found, the failure procedure is called with two arguments, as follows:

(failure insert ignore)

The insert argument is a procedure that takes one argument, as (insert retval). It inserts elt into the set/bag, and returns retval. The ignore argument is a procedure that takes one argument, as (ignore retval). It just returns retval.

The return values of set-search! and bag-search! is the modified set/bag (which may or may not be eq? to the passed one), and the value returned by success or failure procedures.

Note that retval isn’t used in this process; it is just to provide one of the return values of set-search!/bag-search!, for the procedures passed to success or failure are expected to be tail-called.

If there are more than one item that matches elt in a bag, bag-search! only invokes success for the first item it finds. You can recurse into bag-search! in the failure procedure to visit all matching items. It is guaranteed that success and failure procedures are tail-called.

The whole set

Function: set-size set
Function: bag-size bag

[R7RS set] {scheme.set} Returns the number of items in the set/bag.

Function: set-find pred set failure
Function: bag-find pred bag failure

[R7RS set] {scheme.set} Apply pred on each item in the set/bag, and returns the first item on which pred returns true. Since sets and bags are unordered, if there are more than one items that satisfy pred, you won’t know which one will be returned.

If there’re no items that satisfy pred, a thunk failure is called and its result is returned.

Function: set-count pred set
Function: bag-count pred bag

[R7RS set] {scheme.set} Returns the number of items that satisfy pred in the set/bag.

Function: set-any? pred set
Function: bag-any? pred bag

[R7RS set] {scheme.set} Returns true iff any item in the set/bag satisfy pred.

Function: set-every? pred set
Function: bag-every? pred bag

[R7RS set] {scheme.set} Returns true iff every item in the set/bag satisfy pred.

Mapping and folding

Function: set-map comparator proc set
Function: bag-map comparator proc bag

[R7RS set] {scheme.set} Create and return a new set/bag with the comparator comparator, whose items are calculated by applying proc to each element in the original set/bag.

Function: set-for-each proc set
Function: bag-for-each proc bag

[R7RS set] {scheme.set} Apply proc to each element in the set/bag. The result of proc is ignored. Return value is undefined.

Function: set-fold proc seed set
Function: bag-fold proc seed bag

[R7RS set] {scheme.set} For each item in the set/bag, call proc with two arguments, an item and a seed value. What proc returns becomes the next seed value. The seed argument gives the initial seed value, and the last return value of proc will be the result of set-fold/bag-fold.

(bag-fold + 0 (bag eqv-comparator 1 1 2 2 3 3 4 4))
  ⇒ 20
Function: set-filter pred set
Function: bag-filter pred bag

[R7RS set] {scheme.set} Returns a newly created set/bag with the same comparator of the original set/bag, and its content consists of items from the original set/bag that satisfy pred.

(set->list (set-filter odd? (set eqv-comparator 1 2 3 4 5)))
  ⇒ (1 3 5)
Function: set-remove pred set
Function: bag-remove pred bag

[R7RS set] {scheme.set} Returns a newly created set/bag with the same comparator of the original set/bag, and its content consists of items from the original set/bag that does not satisfy pred.

(set->list (set-remove odd? (set eqv-comparator 1 2 3 4 5)))
  ⇒ (2 4)
Function: set-partition pred set
Function: bag-partition pred bag

[R7RS set] {scheme.set} Returns two sets or bags, both have the same comparator of the original set or bag. The first one consists of the items from the original set/bag that satisfy pred, and the second one consists of the items that don’t.

(receive (in out) (set-remove odd? (set eqv-comparator 1 2 3 4 5))
  (values (set->list in)
          (set->list out)))
  ⇒ (1 3 5) and (2 4)
Function: set-filter! pred set
Function: bag-filter! pred bag
Function: set-remove! pred set
Function: bag-remove! pred bag
Function: set-partition! pred set
Function: bag-partition! pred bag

[R7RS set] {scheme.set} Linear update versions of their counterparts (the procedures without !). They work like their respective counterpart, but they are allowed (but not required) to reuse the original set/bag to produce the result(s).

Note that it is not guaranteed that the original set/bag is modified, so you have to use the return value(s) instead of relying on the side effects.

Copying and conversion

Function: set-copy set
Function: bag-copy bag

[R7RS set] {scheme.set} Returns a copy of the set/bag.

Function: set->list set
Function: bag->list bag

[R7RS set] {scheme.set} Returns a list of all items in the set/bag. Since sets and bags are unordered, there’s no guarantee on the order of items.

Function: list->set comparator elt-list
Function: list->bag comparator elt-list

[R7RS set] {scheme.set} Creates a set or a bag with the given comparator, and the list of element. Functionally equivalent to the followings:

(apply set comparator elt-list)
(apply bag comparator elt-list)
Function: list->set! set elt-list
Function: list->bag! bag elt-list

[R7RS set] {scheme.set} Add items in elt-list to the existing set/bag, and returns the updated set/bag. The original set/bag is also modified. Functionally equivalent to the followings:

(apply set-adjoin! set elt-list)
(apply bag-adjoin! bag elt-list)
Function: bag->set bag
Function: set->bag set

[R7RS set] {scheme.set} Conversions between a bag and a set. Returns a newly created bag or set, respectively.

If bag has duplicated items, bag->set coerces them to one item.

Function: set->bag! bag set

[R7RS set] {scheme.set} Adds all items in set to bag, and returns bag. Both bag and set must have the same comparator.

Function: bag->alist bag

[R7RS set] {scheme.set} Returns a list of (item . count), where item is an item in bag, and count is the number of that item in the bag.

Function: alist->bag comparator alist

[R7RS set] {scheme.set} Creates a new bag with comparator, and fills it according to alist, which must be a list of (item . count).

If there’s duplicate items in alist, only fist one counts.

Subsets

Function: set=? set1 set2 …
Function: bag=? bag1 bag2 …

[R7RS set] {scheme.set} Returns true iff all sets/bags have exactly same items.

The comparators of the argument sets/bags are not checked, but assumed to be the same, in terms of the equality of items.

Function: set<? set1 set2 …
Function: bag<? bag1 bag2 …
Function: set>? set1 set2 …
Function: bag>? bag1 bag2 …
Function: set<=? set1 set2 …
Function: bag<=? bag1 bag2 …
Function: set>=? set1 set2 …
Function: bag>=? bag1 bag2 …

[R7RS set] {scheme.set} Returns true iff each preceding set/bag is a proper subset of, a proper superset of, a subset of, or a superset of the following set/bags, respectively.

Again, the comparators of the argument sets/bags are not checked, but assumed to be the same, in terms of the equality of items.

Set theory operations

Function: set-union set1 set2 …
Function: bag-union bag1 bag2 …

[R7RS set] {scheme.set} Returns a newly allocated set or bag which is a union of all the sets/bags.

Function: set-intersection set1 set2 …
Function: bag-intersection bag1 bag2 …

[R7RS set] {scheme.set} Returns a newly allocated set or bag which is an intersection of all the sets/bags.

Function: set-difference set1 set2 …
Function: bag-difference bag1 bag2 …

[R7RS set] {scheme.set} Returns a newly created set or bag that contains items in set1/bag1 except those are also in set2/bag2 ….

(sort (set->list (set-difference (set eqv-comparator 1 2 3 4 5 6 7)
                                 (set eqv-comparator 3 5 7 9 11 13)
                                 (set eqv-comparator 4 8 16 32))))
  ⇒ (1 2 6)
Function: set-xor set1 set2
Function: bag-xor bag1 bag2

[R7RS set] {scheme.set} Returns a newly created set or bag that consists of items that are either in set1/bag1 or set2/bag2, but not in both.

(sort (set->list (set-xor (set eqv-comparator 2 3 5 7 11 13 17)
                          (set eqv-comparator 3 5 7 9 11 13 15))))
  ⇒ (2 9 15 17)
Function: set-union! set1 set2 …
Function: bag-union! bag1 bag2 …
Function: set-intersection! set1 set2 …
Function: bag-intersection! bag1 bag2 …
Function: set-difference! set1 set2 …
Function: bag-difference! bag1 bag2 …
Function: set-xor! set1 set2
Function: bag-xor! bag1 bag2

[R7RS set] {scheme.set} Linear update versions of their corresponding procedures. Those procedures works like their !-less counterparts, except that they are allowed to, but not required to, reuse set1/bag1 to produce the result.

The caller should always use the returned set/bag instead of relying on the side effects.

Bag-specific procedures

Function: bag-sum bag1 bag2 …
Function: bag-sum! bag1 bag2 …

[R7RS set] {scheme.set} Returns a bag that gathers all the items in given bags, counting duplicates. The functional version bag-sum always creates new bag to return. The linear update version bag-sum! is allowed to, but not required to, modify bag1 to produce the result.

(sort (bag->list (bag-sum (bag eqv-comparator 1 1 2 4 5 5 6)
                          (bag eqv-comparator 3 3 5 9))))
  ⇒ (1 1 2 3 3 4 5 5 5 6 9)

Note the difference from bag-union:

(sort (bag->list (bag-union (bag eqv-comparator 1 1 2 4 5 5 6)
                            (bag eqv-comparator 3 3 5 9))))
  ⇒ (1 1 2 3 3 4 5 5 6 9)
Function: bag-product n bag
Function: bag-product! n bag

[R7RS set] {scheme.set} Returns a bag that contains every item as n-times many as the original bag. A fresh bag is created and returned by bag-product, while bag-product! may reuse bag to produce the result.

(sort (bag->list (bag-product 2 (bag eq-comparator 'a 'b 'r 'a))))
  ⇒ (a a a a b b r r)
Function: bag-unique-size bag

[R7RS set] {scheme.set} Returns the number of unique elements in bag.

(bag-unique-size (bag eqv-comparator 1 1 2 2 3 3 4))
 ⇒ 4
Function: bag-element-count bag elt

[R7RS set] {scheme.set} Returns the number of specified element elt in bag.

(bag-element-count (bag eqv-comparator 1 1 2 2 2 3 3) 2)
 ⇒ 3
Function: bag-for-each-unique proc bag

[R7RS set] {scheme.set} For each unique item in bag, calls proc with two arguments: The item, and the count of the item in the bag.

Function: bag-fold-unique proc seed bag

[R7RS set] {scheme.set} For each unique item in bag, calls proc with three arguments: The item, the count of the item, and the previous seed value. The seed argument provides the initial seed value; the result of proc is used for the next seed value, and the last result of proc is returned from bag-fold-unique.

(sort (bag-fold-unique acons '()
        (bag equal-comparator "a" "a" "b" "b" "b" "c" "d"))
      string<? car)
 ⇒ (("a" . 2) ("b" . 3) ("c" . 1) ("d" . 1))
Function: bag-increment! bag elt count
Function: bag-decrement! bag elt count

[R7RS set] {scheme.set} Linear update bag to increase or decrease the count of elt in it by count, which must be an exact integer. Note that the element count won’t get below zero; if a bag has two a’s, and you call (bag-decrement! bag 'a 100), you get a bag with zero a’s.

Comparators

Comparator: set-comparator
Comparator: bag-comparator

[R7RS comparator] {scheme.set} Comparators to be used to compare sets or bags. They don’t provide comparison procedure, for you cannot define a total order among sets or bags. They do provide hash functions.


Next: , Previous: , Up: R7RS large   [Contents][Index]

10.3.6 scheme.charset - R7RS character sets

Module: scheme.charset

Implements character set library, originally defined as SRFI-14. Note that the following character-set procedures and pre-defined charsets are Gauche’s build-in. See Character set.

char-set             char-set?            char-set-contains?
char-set-copy        char-set-complement  char-set-complement!

char-set:lower-case  char-set:upper-case  char-set:title-case
char-set:letter      char-set:digit       char-set:letter+digit
char-set:graphic     char-set:printing    char-set:whitespace
char-set:iso-control char-set:punctuation char-set:symbol
char-set:hex-digit   char-set:blank       char-set:ascii
char-set:empty       char-set:full

In Gauche, the <char-set> class inherits <collection> and implements the collection protocol, so that the generic operations defined in gauche.collection can also be used (see Collection framework).


Next: , Previous: , Up: R7RS character sets   [Contents][Index]

10.3.6.1 Character-set constructors

Function: list->char-set char-list :optional base-cs
Function: list->char-set! char-list base-cs

[R7RS comparator] {scheme.charset} Constructs a character set from a list of characters char-list. If base-cs is given, it must be a character set, and the characters in it are added to the result character set. List->char-set! is allowed, but not required, to reuse base-cs to store the result.

Function: string->char-set s :optional base-cs
Function: string->char-set! s base-cs

[R7RS charset] {scheme.charset} Like list->char-set and list->char-set!, but take a list of characters from a string s.

Function: char-set-filter pred char-set :optional base-cs
Function: char-set-filter! pred char-set base-cs

[R7RS charset] {scheme.charset} Returns a character set containing every character c in char-set such that (pred c) returns true. If a character set base-cs is given, its content is added to the result. The linear update version char-set-filter! is allowed, but not required, to modify base-cs to store the result.

Function: ucs-range->char-set lower upper :optional error? base-cs
Function: ucs-range->char-set! lower upper error? base-cs

[R7RS charset] {scheme.charset} Creates a character set containing every character whose ISO/IEC 10646 UCS-4 code lies in the half-open range [lower,upper).

Function: integer-range->char-set lower upper :optional error? base-cs
Function: integer-range->char-set! lower upper error? base-cs

{scheme.charset}

Function: ->char-set x

[R7RS charset] {scheme.charset} A convenience function to coerce various kinds of objects to a char-set. The argument x can be a collection of characters, a char-set, or a character. If the argument is a char-set, it is returned as-is. If the argument is a character, a char-set with that single character is returned.

Note: R7RS (scheme charset)’s ->char-set only accepts a string, a char-set or a character as an argument. Gauche extends it so that it can accept any collection of characters.


Next: , Previous: , Up: R7RS character sets   [Contents][Index]

10.3.6.2 Character-set comparison

Function: char-set= char-set1 …

[R7RS charset] {scheme.charset} Returns #t iff all the character sets have exactly the same members.

(char-set=)  ⇒ #t
(char-set= (char-set)) ⇒ #t
(char-set= (string->char-set "cba")
           (list->char-set #\a #\b #\c))
  ⇒ #t
Function: char-set<= char-set1 …

[R7RS charset] {scheme.charset} Returns #t iff every char-set argument is a subset of the following char-sets. If no arguments are given, #t is returned.

Function: char-set-hash char-set :optional bound

[R7RS charset] {scheme.charset} Returns a non-negative exact integer as a hash value of char-set. If optional bound argument is given, it must be a positive integer that limits the range of the hash value, which will fall between 0 to (- bound 1), inclusive.


Next: , Previous: , Up: R7RS character sets   [Contents][Index]

10.3.6.3 Character-set iteration

Function: char-set-cursor char-set

[R7RS charset] {scheme.charset} Returns an object that can point to a first character within char-set (here, ‘first’ merely means the beginning of iteration; the order of iteration is implementation-dependent and you can’t assume a specific order). The caller must treat the return value as an opaque object; it can only be used to pass as the cursor argument of char-set-ref, char-set-cursor-next and end-of-char-set?.

Function: char-set-ref char-set cursor

[R7RS charset] {scheme.charset} Returns a character in char-set pointed by cursor.

The cursor argument must be an object returned from char-set-cursor or char-set-cursor-next with char-set. The behavior is undefined if cursor is not a cursor created from char-set.

Function: char-set-cursor-next char-set cursor

[R7RS charset] {scheme.charset} Returns a new cursor for the next character pointed by cursor within char-set.

The cursor argument must be an object returned from char-set-cursor or char-set-cursor-next with char-set. The behavior is undefined if cursor is not a cursor created from char-set.

Function: end-of-char-set? cursor

[R7RS charset] {scheme.charset} Returns #t iff cursor points to the end of the charset.

Function: char-set-fold kons knil char-set

[R7RS charset] {scheme.charset} Iterate over all characters in char-set, calling the procedure kons with a character and the seed value. The return value of kons becomes the next seed value, while knil gives the first seed value. Returns the last seed value. The order of traversal isn’t specified.

Function: char-set-unfold pred fun gen seed :optional base-char-set
Function: char-set-unfold! pred fun gen seed base-char-set

[R7RS charset] {scheme.charset} Build a character set by calling fun on the seed value repeatedly. For each iteration, first pred is applied to the current seed value. If it returns true, a character set that gathers characters generated so far is returned. Otherwise, fun is called on the seed value, which must return a character. Then gen is called on the seed value to obtain the next seed value.

If base-char-set is given, a union of it and the generated characters is returned. The linear-update version char-set-unfold! may modify base-char-set to create the result.

Function: char-set-for-each proc char-set

[R7RS charset] {scheme.charset} Applies proc on each character in char-set. The return value of proc is discarded. Returns undefined value.

Function: char-set-map proc char-set

[R7RS charset] {scheme.charset} Applies proc on each character in char-set, which must return a character. Returns a new charset consists of the characters returned from proc.


Next: , Previous: , Up: R7RS character sets   [Contents][Index]

10.3.6.4 Character-set query

Function: char-set-every pred char-set
Function: char-set-any pred char-set
Function: char-set-count pred char-set

[R7RS charset] {scheme.charset} These procedures apply pred to each character in char-set.

char-set-every returns #f as soon as pred returns #f. Otherwise, it returns the result of the last application of pred.

char-set-any returns as soon as pred returns a true value, and the return value is the one pred returns. If pred returns #f for all characters, #f is returned.

char-set-count returns the number of times pred returns a true value.

Note that char-set can be huge (e.g. a complement of small char-set), which can make these procedures take very long.

Function: char-set->list char-set
Function: char-set->string char-set

[R7RS charset] {scheme.charset} Returns a list of each character, or a string consisting of each character, in char-set, respectively. Be careful to apply this on a large char set.


Previous: , Up: R7RS character sets   [Contents][Index]

10.3.6.5 Character-set algebra

Function: char-set-adjoin char-set char1 …
Function: char-set-adjoin! char-set char1 …

[R7RS charset] {scheme.charset} Returns a character set that adds char1 … to char-set.

The linear update version char-set-adjoin! may modify char-set.

Function: char-set-delete char-set char1 …
Function: char-set-delete! char-set char1 …

[R7RS charset] {scheme.charset} Returns a character set that removes char1 … from char-set. It is noop if char-set doesn’t have char1 ….

The linear update version char-set-delete! may modify char-set.

Function: char-set-union char-set …
Function: char-set-union! char-set1 char-set2 …

[R7RS charset] {scheme.charset} Returns a character set of all characters in any one of char-set …. Without arguments, returns an empty charset.

The linear update version char-set-union! may modify char-set1.

Function: char-set-intersection char-set …
Function: char-set-intersection! char-set1 char-set2 …

[R7RS charset] {scheme.charset} Returns a character set of every character that is in all of char-set …. Without arguments, returns char-set:full.

The linear update version char-set-intersection! may modify char-set1.

Function: char-set-difference char-set1 char-set2 …
Function: char-set-difference! char-set1 char-set2 …

[R7RS charset] {scheme.charset} Returns a character set of every character that is in char-set1 but not in any of char-set2 ….

The linear update version char-set-difference! may modify char-set1.

Function: char-set-xor char-set …
Function: char-set-xor! char-set1 char-set2 …

[R7RS charset] {scheme.charset} With zero arguments, returns an empty charset. With one argument, it is returned as is. With two arguments, returns a character set of every character that is in either one of two sets, but not in both. With more than two arguments, it returns (char-set-xor (char-set-xor set1 set2) set3 …).

The linear update version char-set-xor! may modify char-set1.

Function: char-set-diff+intersection char-set1 char-set2 …
Function: char-set-diff+intersection! char-set1 char-set2 char-set3 …

[R7RS charset] {scheme.charset} Returns two values, the result of (char-set-difference char-set1 char-set2 … and the result of (char-set-intersection char-set1 char-set2 ….


Next: , Previous: , Up: R7RS large   [Contents][Index]

10.3.7 scheme.hash-table - R7RS hash tables

Module: scheme.hash-table

This module provides hash table library, originally defined as srfi-125.

Hash table provided with this module is the same as Gauche’s built-in hash table. However, srfi-125 introduces procedures that conflict with Gauche’s original procedures, so Gauche provides those procedures built-in but under aliases. See Hashtables, for the built-in hash table procedures.

With this module, procedures are provided as defined in R7RS. Use this module when you’re writing portable code.

Srfi-125 also defines compatibility procedures with srfi-69, although saying they’re deprecated. Those deprecated procedures are supported in this module, too.

The following procedures are the same as Gauche’s built-in.

hash-table-unfold   hash-table?       hash-table-contains?
hash-table-exists?  hash-table-empty? hash-table=?
hash-table-mutable? hash-table-ref    hash-table-ref/default
hash-table-set!     hash-table-update!/default
hash-table-clear!   hash-table-size   hash-table-keys
hash-table-values   hash-table-copy   hash-table-empty-copy
hash-table->alist   hash-table-union! hash-table-intersection!
hash-table-difference!                hash-table-xor!

See Hashtables, for the description of those procedures.

The following procedures are also provided as Gauche’s built-in, but with -r7 suffix.

hash-table         hash-table-delete! hash-table-intern!
hash-table-update! hash-table-pop!    hash-table-find
hash-table-count   hash-table-map     hash-table-for-each
hash-table-map!    hash-table-map->list
hash-table-prune!
Function: make-hash-table comparator arg …
Function: make-hash-table equal-proc hash-proc arg …

[R7RS hash-table] {scheme.hash-table} This enhances built-in make-hash-table with the second form, that takes two procedures instead of one comparator, as srfi-69.

In the srfi-69 form, equal-proc is a procedure taking two keys to see if they are the same, and hash-proc is a procedure taking a key to calculate its hash value (nonnegative fixnum). The compatibility form is deprecated and should be avoided in the new code.

The optional arg dots are ignored in Gauche.

Function: hash-table cmpr key value …

[R7RS hash-table] {scheme.hash-table} This is the same as built-in hash-table-r7 (see Hashtables).

Construct a new hash table with key-comparator cmpr. It is populated by key value …, which is a list with keys and values appear alternatively. It is an error if the length of key-value list is not even.

Note that srfi-125 defines this procedure to return an immutable hash table if the implementation supports one. Gauche doesn’t provide immutable hash tables (we do have immutable map instead, see Immutable map), but when you’re writing a portable program, be careful not to modify the table returned by this procedure.

Function: alist->hash-table alist cmpr arg …
Function: alist->hash-table equal-proc hash-proc cmpr arg …

[R7RS hash-table] {scheme.hash-table} This enhances built-in alist->hash-table with the second form, that takes two procedures instead of one comparator, as srfi-69.

In the srfi-69 form, equal-proc is a procedure taking two keys to see if they are the same, and hash-proc is a procedure taking a key to calculate its hash value (nonnegative fixnum). The compatibility form is deprecated and should be avoided in the new code.

The optional arg dots are ignored in Gauche.

Function: hash-table-delete! ht key …

[R7RS hash-table] {scheme.hash-table} This is the same as built-in hash-table-delete!-r7.

Deletes entries associated with the given keys from the table ht. It is ok if ht doesn’t have key. Returns the number of entries that are actually deleted.

It differs from built-in hash-table-delete! in two points: The built-in one can take exactly one key, and returns a boolean indicating if the entry is actually deleted.

Function: hash-table-intern! ht key failure

[R7RS hash-table] {scheme.hash-table} This is the same as built-in hash-table-intern!-r7.

Search key in ht. If it is found, returns the associated value. If it is not found, call failure without artuments, and insert a new entry associating key and the value failure returns, and returns that new value.

Function: hash-table-update! ht key updater :optional failure success

[R7RS hash-table] {scheme.hash-table} This is the same as built-in hash-table-update!-r7. It takes different optional arguments from built-in hash-table-update!.

Updater is a procedure that takes one argument, failure is a thunk, and success is a procedure that takes one argument.

Works the same as follows, except maybe more efficiently.

(hash-table-set! ht key (updater (hash-table-ref ht key failure success)))
Function: hash-table-pop! ht

[R7RS hash-table] {scheme.hash-table} This is the same as built-in hash-table-pop!-r7. It is a completely different procedure as built-in hash-table-pop!.

Removes an arbitrary entry in the hash table ht, and returns the removed entry’s key and value as two values.

If ht is empty, an error is signalled.

Function: hash-table-find proc ht failure

[R7RS hash-table] {scheme.hash-table} This is the same as built-in hash-table-find-r7. It takes different arguments from built-in hash-table-find.

Calls proc with a key and a value of each entry in ht, until proc returns non-false value. If proc returns non-false value, hash-table-find immediately returns it. If proc returns #f for all entries, calls a thunk failure and returns its result.

Function: hash-table-count ht

[R7RS hash-table] {scheme.hash-table} This is the same as built-in hash-table-count-r7.

Calls proc with a key and a value of each entry in ht, and returns the number of times when proc returned true.

Function: hash-table-map proc cmpr ht

[R7RS hash-table] {scheme.hash-table} This is the same as built-in hash-table-map-r7. This is different from built-in hash-table-map.

Creates a fresh hashtable with a key comparator cmpr, then populate it by inserting the key and the result of applying proc on the value of each entry in ht.

Function: hash-table-map! proc ht

[R7RS hash-table] {scheme.hash-table} This is the same as built-in hash-table-map!-r7.

Calls proc on the value of each entry in ht, and update the entry with the result of proc.

Function: hash-table-map->list proc ht

[R7RS hash-table] {scheme.hash-table} This is the same as built-in hash-table-map->list-r7, and same as built-in hash-table-map (not the scheme.hash-table’s hash-table-map) except the order of the arguments.

Apply proc on a key and a value of each entry in ht, in arbitrary order, and returns a list of results.

Function: hash-table-for-each proc ht
Function: hash-table-for-each ht proc

[R7RS hash-table] {scheme.hash-table} Apply proc on a key and a value of each entry in ht. The result of proc is discarded. Returns an unspecified value.

This procedure allows arguments in both order for the compatibility— the first way is the scheme.hash-table recommended one, which is the same as built-in hash-table-for-each-r7, and the latter way is compatible with srfi-69, which is the same as built-in hash-table-for-each.

It is unfortunate that this compatibility thing is extremely confusing; especially in Gauche, you can make anything applicable, so the distinction between procedures and other objects is blurred.

We recommend that you stick to one way or another within a module; if your module uses built-in interface, use (hash-table-for-each ht proc). If your module imports scheme.hash-table, use (hash-table-for-each proc ht).

Function: hash-table-fold proc seed ht
Function: hash-table-fold ht proc seed

[R7RS hash-table] {scheme.hash-table} The proc argument takes three arguments, a key, a value, and the current seed value. The procedure applies proc for each entry in ht, using seed as the first seed value, and using the previous result of proc as the subsequent seed value. Returns the result of the last call of seed.

This procedure allows arguments in both order for the compatibility— the first way is the scheme.hash-table recommended one, which is the same as built-in hash-table-fold-r7, and the latter way is compatible with srfi-69, which is the same as built-in hash-table-fold.

It is unfortunate that this compatibility thing is extremely confusing. We recommend that you stick to one way or another within a module; if your module uses built-in interface, use the second interface. If your module imports scheme.hash-table, use the first interface.

Function: hash-table-prune! proc ht

[R7RS hash-table] {scheme.hash-table} This is the same as built-in hash-table-prune!-r7.

Apply proc on a key and a value of each entry in ht, and deletes the entry if proc returns a true value. This procedure returns an unspecified value.

Function: hash-table-merge! ht1 ht2

[R7RS hash-table] {scheme.hash-table} This is the same as hash-table-union!, and provided just for the compatibility with srfi-69. Deprecated.

Function: hash obj :optional ignore
Function: string-hash obj :optional ignore
Function: string-ci-hash obj :optional ignore
Function: hash-by-identity obj :optional ignore

[R7RS hash-table] {scheme.hash-table} Provided for the compatibility with srfi-69, and are deprecated.

The first three are the same as built-in default-hash, string-hash, and string-ci-hash, except that these accept an optional second argument, which is ignored. Note that hash-by-identity is also defined as the same as default-hash except the ignored optional second argument, per srfi-125, although the name suggests that it would work as if eq-hash.

Do not use these procedures in the new code; you can use comparators instead (default-comparator, string-comparator, string-ci-comparator and eq-comparator, see Predefined comparators). If you do need hash function, you should still avoid hash and hash-by-identity, and use default-hash and eq-hash instead.

Function: hash-table-equivalence-function ht
Function: hash-table-hash-function ht

[R7RS hash-table] {scheme.hash-table} Provided for the compatibility with srfi-69, and are deprecated.

Returns the equivalence function and hash function of a hash table ht.

For the introspection, we recommend to use built-in hash-table-comparator. (Unfortunately, it is not included in scheme.hash-table, though.)


Next: , Previous: , Up: R7RS large   [Contents][Index]

10.3.8 scheme.ideque - R7RS immutable deques

Module: scheme.ideque

This module provides a functional double-ended queue (deque, pronounced as “deck”), with amortized O(1) access of queue operations on either end.

It also serves as a convenient bidirectional list structures in a sense that operations from the end of the list is just as efficient as the ones from the front.

Note: If you don’t need immutability and wants space-efficient deque, you can also use data.ring-buffer as a deque (see Ring buffer).

This module was originally defined as srfi-134, then became a part of R7RS large.

Gauche’s data.ideque is a superset of this module. See Immutable deques.

Function: ideque element …

[R7RS ideque] {scheme.ideque} Returns an ideque with the given elements.

Function: ideque-unfold p f g seed

[R7RS ideque] {scheme.ideque}

Function: ideque-unfold-right p f g seed

[R7RS ideque] {scheme.ideque}

Function: ideque-tabulate size init

[R7RS ideque] {scheme.ideque}

Function: ideque? idq

[R7RS ideque] {scheme.ideque}

Function: ideque-empty? idq

[R7RS ideque] {scheme.ideque}

Function: ideque-add-front idq x
Function: ideque-add-back idq x

[R7RS ideque] {scheme.ideque}

Function: ideque-front idq
Function: ideque-back idq

[R7RS ideque] {scheme.ideque}

Function: ideque-remove-front idq
Function: ideque-remove-back idq

[R7RS ideque] {scheme.ideque}

Function: ideque-reverse idq

[R7RS ideque] {scheme.ideque}

Function: ideque= idq idq2 …

[R7RS ideque] {scheme.ideque}

Function: ideque-ref idq n

[R7RS ideque] {scheme.ideque}

Function: ideque-take idq n
Function: ideque-take-right idq n

[R7RS ideque] {scheme.ideque}

Function: ideque-drop idq n
Function: ideque-drop-right idq n

[R7RS ideque] {scheme.ideque}

Function: ideque-split-at idq n

[R7RS ideque] {scheme.ideque}

Function: ideque-length idq

[R7RS ideque] {scheme.ideque}

Function: ideque-append idq …

[R7RS ideque] {scheme.ideque}

Function: ideque-zip idq idq2 …

[R7RS ideque] {scheme.ideque}

Function: ideque-map proc idq …

[R7RS ideque] {scheme.ideque}

Function: ideque-filter-map proc idq …

[R7RS ideque] {scheme.ideque}

Function: ideque-for-each proc idq …
Function: ideque-for-each-right proc idq …

[R7RS ideque] {scheme.ideque}

Function: ideque-fold proc knil idq …
Function: ideque-fold-right proc knil idq …

[R7RS ideque] {scheme.ideque}

Function: ideque-append-map proc idq …

[R7RS ideque] {scheme.ideque}

Function: ideque-filter pred idq
Function: ideque-remove pred idq

[R7RS ideque] {scheme.ideque}

Function: ideque-partition pred idq

[R7RS ideque] {scheme.ideque}

Function: ideque-find pred idq :optional failure
Function: ideque-find-right pred idq :optional failure

[R7RS ideque] {scheme.ideque}

Function: ideque-take-while pred idq
Function: ideque-take-while-right pred idq

[R7RS ideque] {scheme.ideque}

Function: ideque-drop-while pred idq
Function: ideque-drop-while-right pred idq

[R7RS ideque] {scheme.ideque}

Function: ideque-span pred idq
Function: ideque-break pred idq

[R7RS ideque] {scheme.ideque}

Function: ideque-any pred idq …
Function: ideque-every pred idq …

[R7RS ideque] {scheme.ideque}

Function: ideque->list idq
Function: list->ideque list

[R7RS ideque] {scheme.ideque}

Function: ideque->generator idq
Function: generator->ideque gen

[R7RS ideque] {scheme.ideque}


Next: , Previous: , Up: R7RS large   [Contents][Index]

10.3.9 scheme.generator - R7RS generators

Module: scheme.generator

This module provides generators and accumulators. They were first defined in srfi-121, then enhanced in srfi-158, and finally incorporated R7RS large as (scheme generator).

A generator is a thunk to generate a sequence of values, potentially terminated by EOF. Procedures to deal with generators are provided by gauche.generator, which is a superset of srfi-121. See Generators, for the details.

An accumulator is an opposite of generators. They are procedures that work as consumers. An accumulator takes one argument. When non-eof value is given, the value is stored, and when EOF is given, the accumulated value is returned. How the values are accumulated depends on the accumulator.

Once EOF is given, the accumulator is “finalized”. Subsequent EOF makes it return the same accumulated value. It is undefined if other values are passed after EOF is passed.

The accumulator can be used to parameterize procedures that yield aggregate objects. Consider the following procedure, which takes items from two generators and accumulate them alternatively. (Note that glet* is Gauche’s procedure but not in srfi-158).

(define (intertwine acc gen1 gen2)
  (let loop ()
    (glet* ([a (gen1)]
            [b (gen2)])
      (acc a)
      (acc b)
      (loop)))
  (acc (eof-object)))

The procedure can return various type of collections, without knowing the actual type—the passed accumulator determines it.

(intertwine (list-accumulator) (giota 5) (giota 5 100))
  ⇒ (0 100 1 101 2 102 3 103 4 104)
(intertwine (vector-accumulator) (giota 5) (giota 5 100))
  ⇒ #(0 100 1 101 2 102 3 103 4 104)
(intertwine (bytevector-accumulator) (giota 5) (giota 5 100))
  ⇒ #u8(0 100 1 101 2 102 3 103 4 104)

Note: In Gauche, you can also use classes to parameterize returned container types (e.g. map-to), for many collection classes support builder protocol. See Collection framework, for the details. Accumulator has the flexibility that you can provide more than one ways to construct return value on the same type (e.g. forward and reverse list).

The following generator procedures are explained in gauche.generator section (see Generators):

The following are accumulator procedures:

Function: make-accumulator kons knil finalizer

[R7RS generator] {scheme.generator} Creates and returns an accumulator with a state, whose initial value is knil. When non-EOF value v is passed to the accumulator, kons is called as (kons v state), and its result becomes the new state value. When EOF value is passed, (finalizer state) is called and its result becomes the result of accumulator.

Function: list-accumulator
Function: reverse-list-accumulator

[R7RS generator] {scheme.generator} Creates and returns accumulators that return accumulated value as a list, in the accumulated order (list-accumulator) or the reverse order (reverse-list-accumulator).

Function: vector-accumulator
Function: reverse-vector-accumulator
Function: bytevector-accumulator

[R7RS generator] {scheme.generator} Returns accumulators that return accumulated value as a fresh vector or bytevector (u8vector), in the accumulated order (vector-accumulator, bytevector-accumulator) or the reverse order (reverse-vector-accumulator). There’s no reverse-bytevector-accumulator.

Function: vector-accumulator! vec at
Function: bytevector-accumulator! bvec at

[R7RS generator] {scheme.generator} The vec or bvec argument is a mutable vector or bytevector (u8vector), and is used as a buffer.

Returns an accumulator that stores the accumulated values in the buffer, starting from the index at. It is an error if the accumulator gets more values after the buffer reaches at the end.

Once EOF is passed to the accumulator, vec or bvec is returned, respectively.

Function: string-accumulator

[R7RS generator] {scheme.generator} Returns an accumulator that accepts characters and accumulates them to a string.

Function: sum-accumulator
Function: product-accumulator
Function: count-accumulator

[R7RS generator] {scheme.generator} Returns accumulators that yield a scalar value.

The accumulator created by sum-accumulator and product-accumulator accepts numbers, and keep adding or multiplying it with the accumulated value (the default value is 0 and 1, respectively).

The accumulator created by count-accumulator accepts any objects and just counting it.


Next: , Previous: , Up: R7RS large   [Contents][Index]

10.3.10 scheme.lseq - R7RS lazy sequences

Module: scheme.lseq

This module provides lightweight lazy sequence (lseq), conceptually represented by a pair of element and generator. When the rest of sequence is taken, the generator is evaluated and yields another pair of element and generator, and so on. The overhead is one allocation of a pair per element. It is much lighter than streams (see Stream library), which requires to create a thunk for every element.

Gauche already has built-in support for such lazy sequences; we go further to make it behave like ordinary pairs—that is, if you take cdr of a lazy pair, we automatically forces the generator so it is indistinguishable from an ordinary pair, modulo side effects. See Lazy sequences.

Srfi-127, the original srfi for this module, is a bit ambiguous whether its lazy sequence must be implemented with a pair whose cdr is a generator procedure, or it refers to the pair+generator as a conceptual model. Considering of the purpose of lazy sequence, the concrete implementation shouldn’t matter; that is, the user of lazy sequence should not count on the fact that the lseq is an improper list terminated by a generator procedure. Instead, an lseq should be treated as an opaque object that can be passed to scheme.lseq procedures.

With that premise, we implement this module as just a thin wrapper of Gauche’s native lazy sequence. It is upper-compatible, except that the code that assumes the internal structure could break. Notably, the constructor generator->lseq is the same as Gauche’s built-in, which returns Gauche’s lseq, undistinguishable to the ordinary list.

(procedure? (generator->lseq (generator 1))) 
  ;; => #t, in srfi-127 reference implementation,
  ;;    #f, in our implementation.
Function: lseq? x

[R7RS lseq] {scheme.lseq} Returns true iff x is an object that can be passed to lseq procedures. In Gauche, it returns #t if x is a pair or an empty list, since a lazy pair is indistinguishable from a pair.

Function: lseq=? elt=? lseq1 lseq2

[R7RS lseq] {scheme.lseq} Compare two lseqs element-wise using elt=? and returns #t iff two lseqs are equal.

Function: lseq-car lseq
Function: lseq-first lseq

[R7RS lseq] {scheme.lseq} Returns the first item of lseq. If lseq is empty, an error is raised. In Gauche, these are just aliases of car.

Function: lseq-cdr lseq
Function: lseq-rest lseq

[R7RS lseq] {scheme.lseq} Returns the rest of lseq. If lseq is empty, an error is raised. In Gauche, these are just aliases of cdr.

Function: lseq-take lseq k
Function: lseq-drop lseq k

[R7RS lseq] {scheme.lseq} Returns an lseq that has first k items, or an lseq that skips first k items, respectively.

An error is signaled when the resulting lseq of lseq-take reached at the end of sequence before k items are taken. It is different from Gauche’s ltake, which simply returns () in such case.

On the other hand, lseq-drop is the same as drop in Gauche; it just drops k items from the head of input sequence, regardless of whether it is an ordinary list or lseq.

Function: lseq-realize lseq

[R7RS lseq] {scheme.lseq} Realizes all the elements in lseq, resulting an ordinary list.

Function: lseq->generator lseq

[R7RS lseq] {scheme.lseq} Creates a generator from lseq. In Gauche, this is same as list->generator.

Function: lseq-length lseq

[R7RS lseq] {scheme.lseq} Returns the length of lseq. All the elements in lseq are realized as the side effect. In Gauche, this is same as length.

Function: lseq-append lseq lseq2 …

[R7RS lseq] {scheme.lseq} Append one or more lseqs lazily. This is the same as lappend in Gauche.

Function: lseq-zip lseq lseq2 …

[R7RS lseq] {scheme.lseq} Returns a lazy sequence in which the first element is a list of first elements of lseqs, and so on.

Function: lseq-map proc lseq lseq2 …

[R7RS lseq] {scheme.lseq} Lazy map. The same as Gauche’s lmap. Returns a lazy sequence.

Function: lseq-for-each proc lseq lseq2 …

[R7RS lseq] {scheme.lseq} This one consumes all the input lseqs, applying proc on each corresponding elements of the input sequences for the side effects. In Gauche, it is the same as for-each, for Gauche doesn’t distinguish lseqs and ordinary lists.

Function: lseq-filter pred lseq
Function: lseq-remove pred lseq

[R7RS lseq] {scheme.lseq} Returns an lseq that contains elements from the input lseq that satisfy or don’t satisfy pred, respectively. Lseq-filter is the same as Gauche’s lfilter.

Function: lseq-take-while pred lseq
Function: lseq-drop-while pred lseq

[R7RS lseq] {scheme.lseq} These are the same as Gauche’s ltake-while and drop-while (the latter doesn’t have l-prefix, since it just drops items from the head of the input sequence, regardless of whether it is an ordinary list or an lseq.

Function: lseq-find pred lseq
Function: lseq-find-tail pred lseq
Function: lseq-any pred lseq
Function: lseq-every pred lseq
Function: lseq-index pred lseq
Function: lseq-member pred lseq :optional eq
Function: lseq-memq pred lseq
Function: lseq-memv pred lseq

[R7RS lseq] {scheme.lseq} In Gauche, these are the same as the corresponding list functions, find, find-tail, any, every, list-index, member, memq and memv, respectively, for all of those functions won’t look at input more than necessary so lseqs work just as well as ordinary lists.


Next: , Previous: , Up: R7RS large   [Contents][Index]

10.3.11 scheme.stream - R7RS stream

Module: scheme.stream

This module provides utilities for lazily evaluated streams. It is more heavyweight than lazy sequences (see Lazy sequences), but it strictly implements “as lazy as possible” semantics—elements are never evaluated until it is actually accessed.

The following procedures are provided in Gauche’s util.stream module; see Stream library for their description:

stream-null         stream-cons       stream?          stream-null?
stream-pair?        stream-car        stream-cdr       stream-lambda

define-stream       list->stream      port->stream
stream->list        stream-append     stream-concat    stream-constant
stream-drop-while   stream-filter     stream-fold
stream-for-each     stream-from       stream-iterate   stream-length
stream-let          stream-map        stream-match     stream-of 
stream-range        stream-ref        stream-reverse   stream-scan
stream-take-while   stream-unfold     stream-unfolds   stream-zip

The following macro and procedures have different interface from Gauche’s util.stream module:

stream              stream-take      stream-drop
Macro: stream expr …

[R7RS stream] {scheme.stream} Returns a new stream whose elements are the result of expr …. Arguments won’t be evaluated until required.

This differs from srfi-40 and util.stream’s stream, which is a procedure so arguments are evaluated (see Stream constructors, for the details).

Function: stream-take n stream
Function: stream-drop n stream

[R7RS stream] {scheme.stream} Returns a stream that contains first n elements from stream, or elements without first n elements from it, respectively. If stream has less than n elements, stream-take returns a copy of the entire stream, while stream-drop returns a null stream.

Note that the argument order doesn’t follow the Scheme tradition, which takes the main object (stream in this case) first, then the count. Procedures with the same name is provided in util.stream with the different argument order.


Next: , Previous: , Up: R7RS large   [Contents][Index]

10.3.12 scheme.box - R7RS boxes

Module: scheme.box

This module defines the box datatype, which is a simple container that can hold one Scheme object. It can be used as a minimal data storage, or a sort of mutable indirect “pointer”.

Traditionally a pair (with ignoring its cdr) or a single-element vector has been used for this purpose; in modern Scheme you can also define a record type with one mutable field. Nevertheless, a box is very common abstraction to describe various algorithms, and having common interface to it is useful.

The srfi leaves some details to implementations. Here are our choices:

When you’re writing portable code, be careful not to depend on the equal? behavior.

Function: box val

[R7RS box] {scheme.box} Returns a fresh box object that contains the value val.

Function: box? obj

[R7RS box] {scheme.box} Returns #t iff obj is a box object.

Function: unbox box

[R7RS box] {scheme.box} Returns box’s content.

Function: set-box! box val

[R7RS box] {scheme.box} Mutate box’s content with val. Returns unspecified value.


Next: , Previous: , Up: R7RS large   [Contents][Index]

10.3.13 scheme.list-queue - R7RS list queues

Module: scheme.list-queue

A library of simple queue based on lists. Gauche has a queue support in data.queue module, which also includes MT-safe queue (see Queue). This library is implemented on top of data.queue’s <queue> object and mainly provided for portable code.

The list-queue is just an instance of <queue>, so you can pass a queue created by make-queue to scheme.list-queue API and a list-queue created by make-list-queue to Gauche’s queue API.

Note: Some API of this library requires to return internal pairs the queue uses, for the efficiency. The pair’s car/cdr will be mutated by subsequent queue operation, and also any mutation done on the pair would cause inconsistency in the original queue.

Function: make-list-queue lis :optional last

[R7RS list-queue] {scheme.list-queue} Creates and returns a list-queue whose initial content is lis. In Gauche, a list queue is just an instance of <queue> (see Queue).

The cells in lis are owned by the queue; the caller shouldn’t mutate it afterwards, nor assume its structure remains the same.

The optional last argument must be the last pair of lis. If it is passed, make-list-queue will skip scanning lis and just hold a reference to last as the tail of the queue.

Function: list-queue elt …

[R7RS list-queue] {scheme.list-queue} Creates and returns a list-queue whose initial content is elt …. In Gauche, a list queue is just an instance of <queue> (see Queue).

Function: list-queue-copy queue

[R7RS list-queue] {scheme.list-queue} Returns a copy of a list-queue queue.

Function: list-queue-unfold p f g seed :optional queue

[R7RS list-queue] {scheme.list-queue} Prepend queue with the items generated by (unfold p f g seed) and returns the updated queue. See R7RS lists, for unfold. If queue is omitted, a fresh queue is created.

(list-queue-unfold (pa$ = 5) ; p
                   (pa$ * 2) ; f
                   (pa$ + 1) ; g
                   0         ; seed
                   (list-queue 'x 'y 'z))
 ⇒ a queue containing (0 2 4 6 8 x y z)
Function: list-queue-unfold-right p f g seed :optional queue

[R7RS list-queue] {scheme.list-queue} Append queue with the items generated by (unfold-right p f g seed) and returns the updated queue. See R7RS lists, for unfold-right. If queue is omitted, a fresh queue is created.

(list-queue-unfold-right (pa$ = 5) ; p
                         (pa$ * 2) ; f
                         (pa$ + 1) ; g
                         0         ; seed
                         (list-queue 'x 'y 'z))
 ⇒ a queue containing (x y z 8 6 4 2 0)
Function: list-queue? obj

[R7RS list-queue] {scheme.list-queue} Returns true iff queue is a list-queue. In Gauche, it is the same as queue? in the data.queue module.

Function: list-queue-empty? queue

[R7RS list-queue] {scheme.list-queue} Returns true iff queue is empty. Same as queue-empty? of data.queue.

Function: list-queue-front queue

[R7RS list-queue] {scheme.list-queue} Returns the front element of the queue. An error is thrown if queue is empty. Same as queue-front of data.queue.

Function: list-queue-back queue

[R7RS list-queue] {scheme.list-queue} Returns the rear element of the queue. An error is thrown if queue is empty. Same as queue-rear of data.queue.

Function: list-queue-list queue

[R7RS list-queue] {scheme.list-queue} Returns the internal list of queue. Note that the list would be modified by subsequent operations of queue, and any modification on the list would make queue inconsistent. The primary purpose of this procedure is to implement other queue-related operations with small overhead.

If you merely need a cheap access the content of the queue, consider list-queue-remove-all!. That returns the list of elements of the queue without copying, and simultaneously reset the queue to empty, so it’s safe.

Function: list-queue-fist-last queue

[R7RS list-queue] {scheme.list-queue} Returns two values, the first and last pair of queue. If the queue is empty, two empty lists are returned.

This also returns the internal pair of the queue, so any subsequent operations of queue would change the contents of the pairs, and any modification on the pairs would make queue inconsistent. The purpose of this procedure is to implement other queue-related operations with small overhead. This procedure should not be used in general.

Function: list-queue-add-front! queue elt

[R7RS list-queue] {scheme.list-queue} Add elt to the front of queue. Same as (queue-push! queue elt) of data.queue.

Function: list-queue-add-back! queue elt

[R7RS list-queue] {scheme.list-queue} Add elt to the back of queue. Same as (enqueue! queue elt) of data.queue.

Function: list-queue-remove-front! queue

[R7RS list-queue] {scheme.list-queue} Remove an element from the front of queue and returns the removed element. Throws an error if queue is empty. Same as dequeue! of data.queue.

Function: list-queue-remove-back! queue

[R7RS list-queue] {scheme.list-queue} Remove an element from the back of queue and returns the removed element. Throws an error if queue is empty. This isn’t guaranteed to be efficient; it is O(n) operation where n is the number of elements. In general, if you need this operation frequently, you should consider double-ended queue. (See Immutable deques, and also see Ring buffer.)

Function: list-queue-remove-all! queue

[R7RS list-queue] {scheme.list-queue} Remove all the elements from queue and returns them as a list. The list isn’t copied—this is O(1) operation. This should be preferred over list-queue-list, for it’s safer. In Gauche, this is the same as dequeue-all! in data.queue.

Function: list-queue-set-list! queue lis :optional last

[R7RS list-queue] {scheme.list-queue} Modify queue to have the elements in lis as its element. The original content of queue is discarded. If the optional last argument is provided, it must be the last pair of lis, and the procedure uses that instead of scanning lis, to achieve O(1) operation.

After calling this, lis is owned by queue and it may be mutated. The caller shouldn’t change, or rely on lis afterwards.

Function: list-queue-append queue …

[R7RS list-queue] {scheme.list-queue} Returns a fresh list-queue whose contents are concatenation of queues. The contents of arguments are intact. This is O(n) operation where n is the total number of elements.

Function: list-queue-append! queue …

[R7RS list-queue] {scheme.list-queue} Returns a list-queue whose contents are concatenation of queues. During the operation, the contents of queues may be mutated, and they shouldn’t be used any longer. (In Gauche, to avoid accident, we actually empty all the queues.) It is also noted that the result doesn’t need to be eq? to any of the arguments. This is O(m) operation where m is the total number of queues (as opposed to the number of elements).

Function: list-queue-concatenate queues

[R7RS list-queue] {scheme.list-queue} (apply list-queue-append queues).

Function: list-queue-map proc queue

[R7RS list-queue] {scheme.list-queue} Returns a fresh list-queue whose elements are obtained by applying proc on every elements in queue.

Function: list-queue-map! proc queue

[R7RS list-queue] {scheme.list-queue} Replaces every element in queue by the result of application of proc on the element.

Function: list-queue-for-each proc queue

[R7RS list-queue] {scheme.list-queue} Applies proc on every element of queue. The results are discarded.


Next: , Previous: , Up: R7RS large   [Contents][Index]

10.3.14 scheme.ephemeron - R7RS ephemeron

Module: scheme.ephemeron

This module defined ephemerons, a weak reference structure to hold key-value association. This is originally defined as srfi-142.

Gauche supports weak pointers in the form of weak vectors (see Weak pointers), but it is known that a simple weak pointer (a single pointer that doesn’t prevent the pointed object from being collected) isn’t enough to implement weak key-value association such as mappings.

An ephemeron is a record that points to a key and an associated datum, with the following characteristics:

  1. Reference to the key is weak; it doesn’t prevent the key from being collected if there’s no strong reference to the key, except from the datum associated by the ephemeron.
  2. Reference to the datum is also a kind of weak; it doesn’t prevent the datum from being collected if there’s no strong reference to the datum, and there’s no strong reference to the associated key. Note that the datum is retained as long as the key is retained, even there’s no strong reference to the datum itself.

Implementing the proper ephemeron requires deep integration with the GC. At this moment, Gauche’s ephemeron is implemented separately from GC, and has the following limitations:

Since the timing of collection isn’t specified in the spec, Gauche’s implementation still conforms srfi-142, but in practice you need to be aware of these limitations. Eventually we want to support full ephemeron integrated with GC.

Once the key and/or the datum is collected (we call such ephemeron “broken”), referencing them returns a bogus value. The proper way to use an ephemeron e is the following pattern:

(let ([k (ephemeron-key e)]
      [d (ephemeron-datum e)])
  (if (ephemeron-broken? e)
    (... k and d are invalid ...)
    (... k and d are valid ...)))

You should take values, then check if the ephemeron isn’t broken yet. If you call ephemeron-broken? first, there’s a chance that the ephemeron is broken between the check and the time you reference it.

Function: make-ephemeron key datum

[R7RS ephemeron] {scheme.ephemeron} Create a new ephemeron associating the key to the datum.

Function: ephemeron? obj

[R7RS ephemeron] {scheme.ephemeron} Returns #t iff obj is an ephemeron.

Function: ephemeron-key ephemeron
Function: ephemeron-datum ephemeron

[R7RS ephemeron] {scheme.ephemeron} Returns the key and the datum of ephemeron, respectively. If the ephemeron is already broken, there’s no guarantee on what is returned. Thus you should always call ephemeron-broken? after calling these procedure to ensure the values are meaningful. See the scheme.ephemeron entry for the details.

Function: ephemeron-broken? ephemeron

[R7RS ephemeron] {scheme.ephemeron} Returns #t iff ephemeron has been broken, that is, its key and/or datum may be collected and cannot be reliably retrieved. See the scheme.ephemeron entry for the details.

Function: reference-barrier key

[R7RS ephemeron] {scheme.ephemeron} This procedure does nothing by itself, but guarantees key is strongly reference until returning from this procedure.


Next: , Previous: , Up: R7RS large   [Contents][Index]

10.3.15 scheme.comparator - R7RS comparators

Module: scheme.comparator

This module defines comparators and related procedures. Originally called srfi-128.

Gauche supports comparators fully compatible to scheme.comparator built-in. See Basic comparators, for the following procedures defined in this module.

comparator? comparator-ordered? comparator-hashable?
make-comparator make-pair-comparator
make-list-comparator make-vector-comparator
make-eq-comparator make-eqv-comparator make-equal-comparator

boolean-hash char-hash char-ci-hash string-hash
string-ci-hash symbol-hash number-hash
hash-bound hash-salt

make-default-comparator default-hash
comparator-register-default!

comparator-type-test-predicate comparator-equality-predicate
comparator-ordering-predicate comparator-hash-function
comparator-test-type comparator-check-type comparator-hash

=? <? >? <=? >=? comparator-if<=>

Next: , Previous: , Up: R7RS large   [Contents][Index]

10.3.16 scheme.regex - R7RS regular expressions

Module: scheme.regex

This module provides operations on Scheme Regular Expressions (SRE). Originally defined as srfi-115.

Note that support for this module is not complete. Grapheme syntax is still missing.

Scheme regular expression syntax

Syntax summary

SRE is just an S-expression with the structure summarized below.

With the exception of or, any syntax that takes multiple <sre> processes them in a sequence. In other words (foo <sre> ...) is equivalent to (foo (seq <sre> ...)).

Note: SRE uses the symbol | for alteration, but the vertical bar character is used for symbol escape in Gauche (and R7RS), so you have to write such symbol as |\||. We recommend to use or instead.

    <sre> ::=
     | <string>                    ; A literal string match.
     | <cset-sre>                  ; A character set match.
     | (* <sre> ...)               ; 0 or more matches.
     | (zero-or-more <sre> ...)
     | (+ <sre> ...)               ; 1 or more matches.
     | (one-or-more <sre> ...)
     | (? <sre> ...)               ; 0 or 1 matches.
     | (optional <sre> ...)
     | (= <n> <sre> ...)           ; <n> matches.
     | (exactly <n> <sre> ...)
     | (>= <n> <sre> ...)          ; <n> or more matches.
     | (at-least <n> <sre> ...)
     | (** <n> <m> <sre> ...)      ; <n> to <m> matches.
     | (repeated <n> <m> <sre> ...)

     | (|\||  <sre> ...)           ; Alternation.
     | (or <sre> ...)

     | (:   <sre> ...)             ; Sequence.
     | (seq <sre> ...)
     | ($ <sre> ...)               ; Numbered submatch.
     | (submatch <sre> ...)
     | (-> <name> <sre> ...)               ;  Named submatch.  <name> is
     | (submatch-named <name> <sre> ...)   ;  a symbol.

     | (w/case   <sre> ...)        ; Introduce a case-sensitive context.
     | (w/nocase <sre> ...)        ; Introduce a case-insensitive context.

     | (w/unicode   <sre> ...)     ; Introduce a unicode context.
     | (w/ascii <sre> ...)         ; Introduce an ascii context.

     | (w/nocapture <sre> ...)     ; Ignore all enclosed submatches.

     | bos                         ; Beginning of string.
     | eos                         ; End of string.

     | bol                         ; Beginning of line.
     | eol                         ; End of line.

     | bow                         ; Beginning of word.
     | eow                         ; End of word.
     | nwb                         ; A non-word boundary.
     | (word <sre> ...)            ; An SRE wrapped in word boundaries.
     | (word+ <cset-sre> ...)      ; A single word restricted to a cset.
     | word                        ; A single word.

     | (?? <sre> ...)              ; A non-greedy pattern, 0 or 1 match.
     | (non-greedy-optional <sre> ...)
     | (*? <sre> ...)              ; Non-greedy 0 or more matches.
     | (non-greedy-zero-or-more <sre> ...)
     | (**? <m> <n> <sre> ...)     ; Non-greedy <m> to <n> matches.
     | (non-greedy-repeated <sre> ...)
     | (atomic <sre> ...)          ; Atomic clustering.

     | (look-ahead <sre> ...)      ; Zero-width look-ahead assertion.
     | (look-behind <sre> ...)     ; Zero-width look-behind assertion.
     | (neg-look-ahead <sre> ...)  ; Zero-width negative look-ahead assertion.
     | (neg-look-behind <sre> ...) ; Zero-width negative look-behind assertion.

     | (backref <n-or-name>)       ; Match a previous submatch.
                              

The grammar for cset-sre is as follows.

    <cset-sre> ::=
     | <char>                      ; literal char
     | "<char>"                    ; string of one char
     | <char-set>                  ; embedded SRFI 14 char set
     | (<string>)                  ; literal char set
     | (char-set <string>)
     | (/ <range-spec> ...)        ; ranges
     | (char-range <range-spec> ...)
     | (or <cset-sre> ...)         ; union
     | (|\|| <cset-sre> ...)
     | (and <cset-sre> ...)        ; intersection
     | (& <cset-sre> ...)
     | (- <cset-sre> ...)          ; difference
     | (- <difference> ...)
     | (~ <cset-sre> ...)          ; complement of union
     | (complement <cset-sre> ...)
     | (w/case <cset-sre>)         ; case and unicode toggling
     | (w/nocase <cset-sre>)
     | (w/ascii <cset-sre>)
     | (w/unicode <cset-sre>)
     | any | nonl | ascii | lower-case | lower
     | upper-case | upper | title-case | title
     | alphabetic | alpha | alphanumeric | alphanum | alnum
     | numeric | num | punctuation | punct | symbol
     | graphic | graph | whitespace | white | space
     | printing | print | control | cntrl | hex-digit | xdigit

    <range-spec> ::= <string> | <char>

Basic patterns

<string>

A literal string.

(regexp-search "needle" "hayneedlehay") => #<regexp-match>
(regexp-search "needle" "haynEEdlehay") => #f
(seq <sre> ...)
(: <sre> ...)

A sequence of patterns that should be matched in the same order. This is the same as RE syntax (?:re…)

(regexp-search '(: "one" space "two" space "three") "one two three") => #<regexp-match>
(or <sre> ...)
(|\|| <sre> ...)

Matches one of the given patterns. This is the same as RE syntax pattern1|pattern2|…

(regexp-search ’(or "eeney" "meeney" "miney") "meeney") => #<regexp-match> (regexp-search ’(or "eeney" "meeney" "miney") "moe") => #f

(w/nocase <sre> ...)

Changes to match the given patterns case-insensitively. Sub-patterns can still be made sensitive with w/case. This is the same as RE syntax (?i:re…)

(regexp-search "needle" "haynEEdlehay") => #f
(regexp-search '(w/nocase "needle") "haynEEdlehay") => #<regexp-match>

(regexp-search '(~ ("Aab")) "B") => #<regexp-match>
(regexp-search '(~ ("Aab")) "b") => #f
(regexp-search '(w/nocase (~ ("Aab"))) "B") => #f
(regexp-search '(w/nocase (~ ("Aab"))) "b") => #f
(regexp-search '(~ (w/nocase ("Aab"))) "B") => #f
(regexp-search '(~ (w/nocase ("Aab"))) "b") => #f
(w/case <sre> ...)

Changes to match the given patterns case-sensitively. Sub-patterns can still be made case-insensitive. This is the same as RE syntax (?-i:re…). This is the default.

(regexp-search '(w/nocase "SMALL" (w/case "BIG")) "smallBIGsmall") => #<regexp-match>
(regexp-search '(w/nocase (~ (w/case ("Aab")))) "b") => #f
(w/ascii <sre> ...)

Limits the character sets and other predefined patterns to ASCII. This affects patterns or character sets like any, alpha, (word)

(regexp-search '(w/ascii bos (* alpha) eos) "English") => #<regexp-match>
(regexp-search '(w/ascii bos (* alpha) eos) "Ελληνική") => #f
(w/unicode <sre> ...)

Changes the character sets and other predefined patterns back to Unicode if w/ascii has been used in the outer scope. This is the default.

(regexp-search '(w/unicode bos (* alpha) eos) "English") => #<regexp-match>
(regexp-search '(w/unicode bos (* alpha) eos) "Ελληνική") => #<regexp-match>
(w/nocapture <sre> ...)

Disables capturing for all submatch and submatch-named inside.

(let ((number '($ (+ digit))))
  (cdr
   (regexp-match->list
    (regexp-search `(: ,number "-" ,number "-" ,number)
                   "555-867-5309")))  ; => '("555" "867" "5309")
  (cdr
   (regexp-match->list
    (regexp-search `(: ,number "-" (w/nocapture ,number) "-" ,number)
                   "555-867-5309"))))   => '("555" "5309")

Repeating patterns

(optional <sre> ...)
(? <sre> ...)

Matches the pattern(s) one or zero times.

(regexp-search '(: "match" (? "es") "!") "matches!") => #<regexp-match>
(regexp-search '(: "match" (? "es") "!") "match!") => #<regexp-match>
(regexp-search '(: "match" (? "es") "!") "matche!") => #f
(zero-or-more <sre> ...)
(* <sre> ...)

Matches the pattern(s) zero or more times.

(regexp-search '(: "<" (* (~ #\>)) ">") "<html>") => #<regexp-match>
(regexp-search '(: "<" (* (~ #\>)) ">") "<>") => #<regexp-match>
(regexp-search '(: "<" (* (~ #\>)) ">") "<html") => #f
(one-or-more <sre> ...)
(+ <sre> ...)

Matches the pattern(s) at least once.

(regexp-search '(: "<" (+ (~ #\>)) ">") "<html>") => #<regexp-match>
(regexp-search '(: "<" (+ (~ #\>)) ">") "<a>") => #<regexp-match>
(regexp-search '(: "<" (+ (~ #\>)) ">") "<>") => #f
(at-least n <sre> ...)
(>= n <sre> ...)

Matches the pattern(s) at least n times.

(regexp-search '(: "<" (>= 3 (~ #\>)) ">") "<table>") => #<regexp-match>
(regexp-search '(: "<" (>= 3 (~ #\>)) ">") "<pre>") => #<regexp-match>
(regexp-search '(: "<" (>= 3 (~ #\>)) ">") "<tr>") => #f
(exactly n <sre> ...)
(= n <sre> ...)

Matches the pattern(s) exactly n times.

(regexp-search '(: "<" (= 4 (~ #\>)) ">") "<html>") => #<regexp-match>
(regexp-search '(: "<" (= 4 (~ #\>)) ">") "<table>") => #f
(repeated from to <sre> ...)
(** from to <sre> ...)

Matches the pattern(s) at least from times and up to to times.

(regexp-search '(: (= 3 (** 1 3 numeric) ".") (** 1 3 numeric)) "192.168.1.10") => #<regexp-match>
(regexp-search '(: (= 3 (** 1 3 numeric) ".") (** 1 3 numeric)) "192.0168.1.10") => #f

Submatch Patterns

(submatch <sre> ...)
($ <sre> ...)

Captures the matched string. Each capture is numbered increasing from one (capture zero is the entire matched string). For nested captures, the numbering scheme is depth-first walk.

(submatch-named <name> <sre> ...)
(-> <name> <sre> ...)

Captures the matched string and assigns a name to it in addition to a number. This is the equivalent of (?<name>re…)

(backref <n-or-name>)

Matches a previously matched submatch. This is the same as RE syntax \n or \k<name>.

Character Sets

<char>

A character set contains a single character.

(regexp-matches '(* #\-) "---") => #<regexp-match>
(regexp-matches '(* #\-) "-_-") => #f
"<char>"

A character set contains a single character. This is technically ambiguous with SRE matching a literal string. However the end result of both syntaxes is the same.

<char-set>

A SRFI-14 character set.

Note that while currently there is no portable written representation of SRFI 14 character sets, you can use Gauche reader syntax #[char-set-spec], see Character set.

(regexp-partition `(+ ,char-set:vowels) "vowels")
  => ("v" "o" "w" "e" "ls")
(char-set <string>)
(<string>)

A character set contains the characters in the given string. This is the same as `(char-set ,(string->char-set <string>)).

(regexp-matches '(* ("aeiou")) "oui") => #<regexp-match>
(regexp-matches '(* ("aeiou")) "ouais") => #f
(regexp-matches '(* ("e\x0301")) "e\x0301") => #<regexp-match>
(regexp-matches '("e\x0301") "e\x0301") => #f
(regexp-matches '("e\x0301") "e") => #<regexp-match>
(regexp-matches '("e\x0301") "\x0301") => #<regexp-match>
(regexp-matches '("e\x0301") "\x00E9") => #f
(char-range <range-spec> ...)
(/ <range-spec> ...)

A character set contains the characters within <range-set>. This is the same as RE syntax [].

(regexp-matches '(* (/ "AZ09")) "R2D2") => #<regexp-match>
(regexp-matches '(* (/ "AZ09")) "C-3PO") => #f
(or <cset-sre> ...)
(|\|| <cset-sre> ...)

A shorthand for `(char-set ,(char-set-union <cset-sre>...)).

(complement <cset-sre> ...)
(~ <cset-sre> ...)

A shorthand for `(char-set ,(char-set-complement <cset-sre>...)).

(difference <cset-sre> ...)
(- <cset-sre> ...)

A shorthand for `(char-set ,(char-set-difference <cset-sre>...)).

(regexp-matches '(* (- (/ "az") ("aeiou"))) "xyzzy") => #<regexp-match>
(regexp-matches '(* (- (/ "az") ("aeiou"))) "vowels") => #f
(and <cset-sre> ...)
(& <cset-sre> ...)

A shorthand for `(char-set ,(char-set-intersection <cset-sre>...)).

(regexp-matches '(* (& (/ "az") (~ ("aeiou")))) "xyzzy") => #<regexp-match>
(regexp-matches '(* (& (/ "az") (~ ("aeiou")))) "vowels") => #f
(w/case <cset-sre>)
(w/nocase <cset-sre>)
(w/ascii <cset-sre>)
(w/unicode <cset-sre>)

This is similar to the SRE equivalent, listed to indicate that they can also be applied on character sets.

Named Character Sets

Note that if w/ascii is in effect, these character sets will return the ASCII subset. Otherwise they return full Unicode ones.

any

Matches any character. This is the . in regular expression.

nonl

Matches any character other than #\return or #\newline.

ascii

A shorthand for `(char-set ,char-set:ascii).

lower-case
lower

A shorthand for `(char-set ,char-set:lower-case).

upper-case
upper

A shorthand for `(char-set ,char-set:upper-case).

title-case
title

A shorthand for `(char-set ,char-set:title-case).

alphabetic
alpha

A shorthand for `(char-set ,char-set:letter).

numeric
num

A shorthand for `(char-set ,char-set:digit).

alphanumeric
alphanum
alnum

A shorthand for `(char-set ,char-set:letter+digit).

punctuation
punct

A shorthand for `(char-set ,char-set:punctuation).

symbol

A shorthand for `(char-set ,char-set:symbol).

graphic
graph

A shorthand for `(char-set ,char-set:graphic).

(or alphanumeric punctuation symbol)
whitespace
white
space

A shorthand for `(char-set ,char-set:whitespace).

printing
print

A shorthand for `(char-set ,char-set:printing).

control
cntrl

A character set contains ASCII characters with from 0 to 31.

hex-digit
xdigit

A shorthand for `(char-set ,char-set:hex-digit).

Boundary Assertions

bos
eos

Matches the beginning of the string. If start/end parameters are specified, matches the start or end of the substring as specified.

bol
eol

Matches the beginning or end of a line (or the string). For single line matching, this is the same as bos and eos. A line is interpreted the same way with read-line.

bow
eow

Matches the beginning or the end of a word.

  (regexp-search '(: bow "foo") "foo") => #<regexp-match>
  (regexp-search '(: bow "foo") "<foo>>") => #<regexp-match>
  (regexp-search '(: bow "foo") "snafoo") => #f
  (regexp-search '(: "foo" eow) "foo") => #<regexp-match>
  (regexp-search '(: "foo" eow) "foo!") => #<regexp-match>
  (regexp-search '(: "foo" eow) "foobar") => #f
nwb

A shorthand for (neg-look-ahead (or bow eow)).

(word <sre> ...)

Matches the word boundary around the given SRE:

(: bow <sre> ... eow)
(word+ <cset-sre> ...)

Matches a single word composed of characters of the given characters sets:

(word (+ (and (or alphanumeric "_") (or cset-sre ...))))
word

A shorthand for (word+ any).

Non-Greedy Patterns

(non-greedy-optional <sre> ...)
(?? <sre> ...)

The non-greedy equivalent of (optional <sre>...). This is the same as RE syntax re??

(non-greedy-zero-or-more< <sre> ...)
(*? <sre> ...)

The non-greedy equivalent of (zero-or-more <sre>...). This is the same as RE syntax re*?

(non-greedy-repeated <m> <n> <sre> ...)
(**? <m> <n> <sre> ...)

The non-greedy equivalent of (repeated <sre>...). This is the same as RE syntax re{n,m}?

(atomic <sre> ...)

Atomic clustering. Once <sre> ... matches, the match is fixed; even if the following pattern fails, the engine won’t backtrack to try the alternative match in <sre> .... This is Gauche extension and is the same as RE syntax (?>pattern)

Look Around Patterns

(look-ahead <sre> ...)

Zero-width look-ahead assertion. Asserts the sequence matches from the current position, without advancing the position. This is the same as RE syntax (?=pattern)

(regexp-matches '(: "regular" (look-ahead " expression") " expression") "regular expression")=> #<regexp-match>
(regexp-matches '(: "regular" (look-ahead " ") "expression") "regular expression")=> #f
(look-behind <sre> ...)

Zero-width look-behind assertion. Asserts the sequence matches behind the current position, without advancing the position. It is an error if the sequence does not have a fixed length. This is the same as RE syntax (?<=pattern)

(neg-look-ahead <sre> ...)

Zero-width negative look-ahead assertion. This is the same as RE syntax (?!pattern)

(neg-look-behind <sre> ...)

Zero-width negative look-behind assertion. This is the same as RE syntax (?<!pattern)

Using regular expressions

Function: regexp re

[R7RS regex] {scheme.regex} Compiles the given Scheme Regular Expression into a <regexp> object. If re is already a regexp object, the object is returned as-is.

Macro: rx sre

[R7RS regex] {scheme.regex} A macro shorthand for (regexp `(: sre ...)).

Function: regexp->sre re

[R7RS regex] {scheme.regex} Returns the SRE corresponding to the given given regexp object. Note that if the regexp object is not created from an SRE, it may contain features that cannot be expressed in SRE and cause an error.

Function: char-set->sre char-set

[R7RS regex] {scheme.regex} Returns the SRE of the given character set. Currently this is not optimized. If you convert any to SRE for example, you may get an SRE listing every single character.

Function: valid-sre? obj

[R7RS regex] {scheme.regex} Returns true iff obj can be safely passed to regexp.

Function: regexp? obj

[R7RS regex] {scheme.regex} Returns true iff obj is a regexp.

Function: regexp-matches re str [start [end]]

[R7RS regex] {scheme.regex} Returns an <regexp-match> object if re successfully matches the entire string str or optionally from start (inclusive) to end (exclusive), or #f is the match fails.

For convenience, end accepts #f and interprets it as the end of the string.

The regexp-match object will contain information needed to extract any submatches.

Function: regexp-matches? re str [start [end]]

[R7RS regex] {scheme.regex} Similar to regexp-matches but returns #t instead of a <regexp-match> object.

Function: regexp-search re str [start [end]]

[R7RS regex] {scheme.regex} Similar to regexp-matches except that re only has to match a substring in str instead.

Function: regexp-fold re kons knil str [finish [start [end]]]

[R7RS regex] {scheme.regex} Calls the procedure kons for every match found in str with following four arguments:

If finish is given, it is called after all matches with the same parameters as calling kons except that #f is passed instead of <regexp-match> and the result is returned. Otherwise the result of the last kons call is returned.

   (regexp-fold 'word
                (lambda (i m str acc)
                  (let ((s (regexp-match-submatch m 0)))
                   (cond ((assoc s acc)
                          => (lambda (x) (set-cdr! x (+ 1 (cdr x))) acc))
                         (else `((,s . 1) ,@acc)))))
                '()
                "to be or not to be")
   => '(("not" . 1) ("or" . 1) ("be" . 2) ("to" . 2))
Function: regexp-extract re str [start [end]]

[R7RS regex] {scheme.regex} Returns a list of matched string or an empty list if no matches.

   (regexp-extract '(+ numeric) "192.168.0.1")
   => ("192" "168" "0" "1")
Function: regexp-split re str [start [end]]

[R7RS regex] {scheme.regex} Returns a list of not matched substrings. This can be seen as the opposite of regexp-extract where the matched strings are removed instead of returned.

   (regexp-split '(+ space) " fee fi  fo\tfum\n")
   => ("fee" "fi" "fo" "fum")
   (regexp-split '(",;") "a,,b,")
   => ("a" "" "b" "")
   (regexp-split '(* numeric) "abc123def456ghi789")
   => ("abc" "def" "ghi" "")
Function: regexp-partition re str [start [end]]

[R7RS regex] {scheme.regex} Returns a list of all matched and not matched substrings. In other words it’s the combination of regexp-extract and regexp-split where the boundary of matched strings are used to split the original string.

   (regexp-partition '(+ (or space punct)) "")
   => ("")
   (regexp-partition '(+ (or space punct)) "Hello, world!\n")
   => ("Hello" ", " "world" "!\n")
   (regexp-partition '(+ (or space punct)) "¿Dónde Estás?")
   => ("" "¿" "Dónde" " " "Estás" "?")
   (regexp-partition '(* numeric) "abc123def456ghi789")
   => ("abc" "123" "def" "456" "ghi" "789")
Function: regexp-replace re str subst [start [end [count]]]

[R7RS regex] {scheme.regex} Returns a new string where the first matched substring is replaced with subst. If count is specified, the count-th match will be replaced instead of the first one.

subst can be either a string (the replacement), an integer or a symbol to refer to the capture group that will be used as the replacement, or a list of those.

The special symbols pre and post use the substring to the left or right of the match as replacement, respectively.

As a Gauche extension, subst could also be a procedure, which is called with the given match object and the result will be used as the replacement.

The optional parameters start and end restrict both the matching and the substitution, to the given indices, such that the result is equivalent to omitting these parameters and replacing on (substring str start end). As a convenience, a value of #f for end is equivalent to (string-length str).

   (regexp-replace '(+ space) "one two three" "_")
   => "one_two three"
   (regexp-replace '(+ space) "one two three" "_" 0 #f 0)
   => "one_two three"
   (regexp-replace '(+ space) "one two three" "_" 0 #f 1)
   => "one two_three"
   (regexp-replace '(+ space) "one two three" "_" 0 #f 2)
   => "one two three"

Note that Gauche also has a builtin procedure of the same name, but works slightly differently, see Using regular expressions.

Function: regexp-replace-all re str subst [start [end]]

[R7RS regex] {scheme.regex} Returns a new string where all matches in str are replaced with subst. subst can also take a string, a number, a symbol or a procedure similar to regexp-replace.

(regexp-replace-all '(+ space) "one two three" "_")
   => "one_two_three"

Note that Gauche also has a builtin procedure of the same name, but works slightly differently, see Using regular expressions.

Function: regexp-match? obj

[R7RS regex] {scheme.regex} Returns true iff obj is a <regexp-match> object.

(regexp-match? (regexp-matches "x" "x"))  => #t
(regexp-match? (regexp-matches "x" "y"))  => #f
Function: regexp-match-count regexp-match

[R7RS regex] {scheme.regex} Returns the number of matches in match except the implicit zero full match. This is just an alias of rxmatch-num-matches minus one.

(regexp-match-count (regexp-matches "x" "x"))  => 0
(regexp-match-count (regexp-matches '($ "x") "x"))  => 1
Function: regexp-match-submatch regexp-match field

[R7RS regex] {scheme.regex} This is an alias of rxmatch-substring

   (regexp-match-submatch (regexp-search 'word "**foo**") 0)  => "foo"
   (regexp-match-submatch
    (regexp-search '(: "*" ($ word) "*") "**foo**") 0)  => "*foo*"
   (regexp-match-submatch
    (regexp-search '(: "*" ($ word) "*") "**foo**") 1)  => "foo"
Function: regexp-match-submatch-start regexp-match field

[R7RS regex] {scheme.regex} This is an alias of regexp-match-submatch-start.

   (regexp-match-submatch-start
    (regexp-search 'word "**foo**") 0)  => 2
   (regexp-match-submatch-start
    (regexp-search '(: "*" ($ word) "*") "**foo**") 0)  => 1
   (regexp-match-submatch-start
    (regexp-search '(: "*" ($ word) "*") "**foo**") 1)  => 2
Function: regexp-match-submatch-end regexp-match field

[R7RS regex] {scheme.regex} This is an alias of regexp-match-submatch-end.

   (regexp-match-submatch-end
    (regexp-search 'word "**foo**") 0)  => 5
   (regexp-match-submatch-end
    (regexp-search '(: "*" ($ word) "*") "**foo**") 0)  => 6
   (regexp-match-submatch-end
    (regexp-search '(: "*" ($ word) "*") "**foo**") 1)  => 5
Function: regexp-match->list regexp-match

[R7RS regex] {scheme.regex} This is an alias of rxmatch-substrings

   (regexp-match->list
    (regexp-search '(: ($ word) (+ (or space punct)) ($ word)) "cats & dogs"))
    => '("cats & dogs" "cats" "dogs")

Next: , Previous: , Up: R7RS large   [Contents][Index]

10.3.17 scheme.mapping - R7RS mappings

Module: scheme.mapping
Module: scheme.mapping.hash

This module defines immutable mappings from keys to values. Originally called srfi-146 and srfi-146.hash.

The scheme.mapping module provides mapping objects, where keys have total order. The scheme.mapping.hash module provides hashmap objects, where keys can be hashed.

Currently, Gauche uses built-in <tree-map> for the mapping object, and built-in <hash-table> for the hashmap object. The actual implementation may be changed in future versions, so the user must not rely on the underlying implementations.

The caller must treat mappings and hashmaps as immutable object. The modules also provide “linear update” APIs, which is allowed to mutate the mappings passed to the arguments, under assumption that the argument won’t be used afterwards. The linear update APIs are marked with ! at the end of the name.


Next: , Previous: , Up: R7RS mappings   [Contents][Index]

10.3.17.1 Mappings

Class: <mapping>

{scheme.mapping} On Gauche, this is just an alias of <tree-map>.

Constructors

Function: mapping comparator key value …

[R7RS mapping] {scheme.mapping} Creates a new mapping with the given comparator, whose initial content is provided by key value ….

The comparator argument must be a comparator (see Basic comparators).

The key value … arguments must be even length, alternating keys and values.

(define m (mapping default-comparator 'a 1 'b 2))

(mapping-ref m 'a) ⇒ 1
(mapping-ref m 'b) ⇒ 2
Function: mapping-unfold p f g seed comparator

[R7RS mapping] {scheme.mapping} Creates a new mapping, whose content is populated by three procedures, p, f and g, and a seed value seed, as follows.

In each iteration, we have a current seed value, whose initial value is seed.

First, p, a stop predicate, is applied to the current seed value. If it returns true, we stop iteration and returns the new mapping.

Next, f is applied to the current seed value. It must return two values. The first one is for a key and the second one for the value. We add this pair to the mapping.

Then, g is applied to the current seed value. The result becomes the seed value of the next iteration. And we iterate.

The following example creates a mapping that maps ASCII characters to their character codes:

(mapping-unfold (cut >= <> 128)
                (^c (values (integer->char c) c))
                (cut + <> 1)
                0
                default-comparator)
Function: mapping/ordered comparator key value …

[R7RS mapping] {scheme.mapping} Similar to mapping, but keys are given in the ascending order w.r.t. the comparator. An implementation may use more efficient algorithm than mapping. In Gauche, this is the same as mapping at this moment.

Function: mapping-unfold/ordered p f g seed comparator

[R7RS mapping] {scheme.mapping} Similar to mapping-unfold, but keys are generated in the ascending order w.r.t. the comparator. An implementation may use more efficient algorithm than mapping-unfold. In Gauche, this is the same as mapping-unfold at this moment.

Predicates

Function: mapping? obj

[R7RS mapping] {scheme.mapping} Returns #t iff obj is a mapping object.

Function: mapping-empty? m

[R7RS mapping] {scheme.mapping} M must be a mapping. Returns #t if m is empty, #f otherwise. In Gauche, this is same as tree-map-empty? (see Treemaps).

Function: mapping-contains? m key

[R7RS mapping] {scheme.mapping} M must be a mapping. Returns #t if m has an entry with key, #f otherwise. In Gauche, this is same as tree-map-exists? (see Treemaps).

Function: mapping-disjoint? m1 m2

[R7RS mapping] {scheme.mapping} Returns #t iff two mappings m1 and m2 have no keys in common. In other words, there’s no such key K that satisfy both (mapping-contains? m1 K) and (mapping-contains? m2 K).

Accessors

Function: mapping-ref m key :optional failure success

[R7RS mapping] {scheme.mapping} Get the value from a mapping m associated with key, and calls success on the value, and returns its result. If m doesn’t have key, failure is invoked with no arguments and its result is returned. Both success and failure is called in tail context.

When failure is omitted and key is not found, an error is signaled. When success is omitted, identity is assumed.

Function: mapping-ref/default m key default

[R7RS mapping] {scheme.mapping} Returns the value associated to key from a mapping m. If m doesn’t have key, default is returned.

Function: mapping-key-comparator m

[R7RS mapping] {scheme.mapping} Returns a comparator used to compare keys in a mapping m. See Basic comparators, for the details of comparators.

Updaters

Note that the basic premise of mappings srfi is to treat mappings as immutable. Each updating operation comes with a purely functional version (without bang) and a linear update version (with bang), but the linear update version may not require to destructively modiy the passed mapping; it’s merely a hint that it may reuse the argument for the efficiency. You always need to use the returned mapping as the result of update. If you use linear update versions, you shouldn’t use the passed mapping afterwards, for there’s no guarantee how the state of the passed mapping is.

Function: mapping-adjoin m arg …
Function: mapping-adjoin! m arg …

[R7RS mapping] {scheme.mapping} The arg … are alternating between key and value. Returns a mapping that contains all the entries in m plus given keys and values, with the same comparator as m. Linear update version mapping-adjoin! may destructively modify m to create the return value, while mapping-adjoin creates a new mapping.

Arguments are processed in order. If there’s already an entry in m with the same key as given to arg, the original entry remains.

(mapping-adjoin (mapping default-comparator 'a 1 'b 2) 'c 3 'a 4 'c 5)
 ⇒ mapping with a → 1, b → 2, c → 3
Function: mapping-set m arg …
Function: mapping-set! m arg …

[R7RS mapping] {scheme.mapping} The arg … are alternating between key and value. Returns a mapping that contains all the entries in m plus given keys and values, with the same comparator as m. Linear update version mapping-set! may destructively modify m to create the return value, while mapping-set creates a new mapping.

Arguments are processed in order. If there’s already an entry in m with the same key as given to arg, the new key-value pair supersedes the old one.

(mapping-set (mapping default-comparator 'a 1 'b 2) 'c 3 'a 4 'c 5)
 ⇒ mapping with a → 4, b → 2, c → 5
Function: mapping-replace m key value
Function: mapping-replace! m key value

[R7RS mapping] {scheme.mapping} If the mapping m has an entry of key, return a mapping with the value of the entry replaced for value. If m doesn’t have an entry with key, m is returned unchanged.

Linear update version mapping-replace! may destructively modify m to produce the return value, while mapping-replace creates a new mapping.

(mapping-replace (mapping default-comparator 'a 1 'b 2) 'a 3)
 ⇒ mapping with a → 3, b → 2

(mapping-replace (mapping default-comparator 'a 1 'b 2) 'c 3)
 ⇒ mapping with a → 1, b → 2
Function: mapping-delete m key …
Function: mapping-delete! m key …

[R7RS mapping] {scheme.mapping} Returns a mapping that is the same as m except its entries with any of the given key … being removed. Keys that are not in m are ignored.

Linear update version mapping-delete! may destructively modify m to produce the return value, while mapping-delete creates a new mapping.

Function: mapping-delete-all m key-list
Function: mapping-delete-all! m key-list

[R7RS mapping] {scheme.mapping} Returns a mapping that is the same as m except its entries with any of the given keys in key-list being removed. Keys that are not in m are ignored.

Linear update version mapping-delete-all! may destructively modify m to produce the return value, while mapping-delete-all creates a new mapping.

Function: mapping-intern m key make-value
Function: mapping-intern! m key make-value

[R7RS mapping] {scheme.mapping} Looks up key in the mapping m, and returns two values, m and the associated value. If m does not contain an entry with key, a thunk make-value is invoked, and creates a new mapping that contains all entries in m plus a new entry with key and the return value of make-value, then returns the new mapping and the return value of make-value.

Linear update version mapping-intern! may destructively modify m to produce the return value, while mapping-intern creates a new mapping.

(mapping-intern (mapping default-comparator 'a 1) 'b (^[] 2))
  ⇒
  mapping with a → 1, b → 2
  and
  2

(mapping-intern (mapping default-comparator 'a 1) 'a (^[] 2))
  ⇒
  mapping with a → 1
  and
  1
Function: mapping-update m key updater :optional failure success
Function: mapping-update! m key updater :optional failure success

[R7RS mapping] {scheme.mapping} Semantically equivalent to this:

(mapping-set m var
  (updater (mapping-ref m key failure success)))

The failure and success optional arguments are procedures with zero and one arguments, respectively. When omitted, failure defaults to a thunk that raises an error, and success defaults to identity.

First, key is looked up in m. If an entry is found, the associated value is passed to success; otherwise, failure is called with no arguments. Either way, let the returned value be v0.

Then, v0 is passed to updater. Let its result be v1.

Finally, a mapping with the same entries as m except the value of key is altered to v1 is returned.

Linear update version mapping-update! may destructively modify m to produce the return value, while mapping-update creates a new mapping.

(mapping-update (mapping default-comparator 'a 1)
                'a (pa$ + 1))
 ⇒ mapping with a → 2

(mapping-update (mapping default-comparator)
                'a (pa$ + 1) (^[] 0))
 ⇒ mapping with a → 1
Function: mapping-update/default m key updater default
Function: mapping-update!/default m key updater default

[R7RS mapping] {scheme.mapping}

Function: mapping-pop m :optional failure
Function: mapping-pop! m :optional failure

[R7RS mapping] {scheme.mapping}

Function: mapping-search m k failure success
Function: mapping-search! m k failure success

[R7RS mapping] {scheme.mapping}

The whole mapping

Function: mapping-size m

[R7RS mapping] {scheme.mapping}

Function: mapping-find pred m failure

[R7RS mapping] {scheme.mapping}

Function: mapping-count pred m

[R7RS mapping] {scheme.mapping}

Function: mapping-any? pred m
Function: mapping-every? pred m

[R7RS mapping] {scheme.mapping}

Function: mapping-keys m
Function: mapping-values m

[R7RS mapping] {scheme.mapping}

Function: mapping-entries m

[R7RS mapping] {scheme.mapping}

Mapping and folding

Function: mapping-map proc comparator m

[R7RS mapping] {scheme.mapping}

Function: mapping-map/monotone proc comparator m
Function: mapping-map/monotone! proc comparator m

[R7RS mapping] {scheme.mapping}

Function: mapping-for-each proc m

[R7RS mapping] {scheme.mapping}

Function: mapping-fold kons knil m

[R7RS mapping] {scheme.mapping}

Function: mapping-fold/reverse kons knil m

[R7RS mapping] {scheme.mapping}

Function: mapping-map->list proc m

[R7RS mapping] {scheme.mapping}

Function: mapping-filter pred m
Function: mapping-filter! pred m

[R7RS mapping] {scheme.mapping}

Function: mapping-remove pred m
Function: mapping-remove! pred m

[R7RS mapping] {scheme.mapping}

Function: mapping-partition pred m
Function: mapping-partition! pred m

[R7RS mapping] {scheme.mapping}

Copying and conversion

Function: mapping-copy m

[R7RS mapping] {scheme.mapping}

Function: mapping->alist m

[R7RS mapping] {scheme.mapping}

Function: alist->mapping comparator alist

[R7RS mapping] {scheme.mapping}

Function: alist->mapping! m alist

[R7RS mapping] {scheme.mapping}

Function: alist->mapping/ordered comparator alist
Function: alist->mapping/ordered! m alist

[R7RS mapping] {scheme.mapping}

Submappings

Function: mapping=? comparator m1 m2 …

[R7RS mapping] {scheme.mapping}

Function: mapping<? comparator m1 m2 …
Function: mapping<=? comparator m1 m2 …
Function: mapping>? comparator m1 m2 …
Function: mapping>=? comparator m1 m2 …

[R7RS mapping] {scheme.mapping}

Set operations

Function: mapping-union m1 m2 …
Function: mapping-union! m1 m2 …

[R7RS mapping] {scheme.mapping}

Function: mapping-intersection m1 m2 …
Function: mapping-intersection! m1 m2 …

[R7RS mapping] {scheme.mapping}

Function: mapping-difference m1 m2 …
Function: mapping-difference! m1 m2 …

[R7RS mapping] {scheme.mapping}

Function: mapping-xor m1 m2 …
Function: mapping-xor! m1 m2 …

[R7RS mapping] {scheme.mapping}

Mappings with ordered keys

Function: mapping-min-key m
Function: mapping-max-key m

[R7RS mapping] {scheme.mapping}

Function: mapping-min-value m
Function: mapping-max-value m

[R7RS mapping] {scheme.mapping}

Function: mapping-min-entry m
Function: mapping-max-entry m

[R7RS mapping] {scheme.mapping}

Function: mapping-key-predecessor m obj failure
Function: mapping-key-successor m obj failure

[R7RS mapping] {scheme.mapping}

Function: mapping-range= m obj
Function: mapping-range< m obj
Function: mapping-range<= m obj
Function: mapping-range> m obj
Function: mapping-range>= m obj

[R7RS mapping] {scheme.mapping}

Function: mapping-range=! m obj
Function: mapping-range<! m obj
Function: mapping-range<=! m obj
Function: mapping-range>! m obj
Function: mapping-range>=! m obj

[R7RS mapping] {scheme.mapping}

Function: mapping-split m obj
Function: mapping-split! m obj

[R7RS mapping] {scheme.mapping}

Function: mapping-catenate comparator m1 key value m2
Function: mapping-catenate! m1 key value m2

[R7RS mapping] {scheme.mapping}

Comparators

Function: make-mapping-comparator comparator

[R7RS mapping] {scheme.mapping}

Variable: mapping-comparator

[R7RS mapping] {scheme.mapping}


Previous: , Up: R7RS mappings   [Contents][Index]

10.3.17.2 Hashmaps

Constructors

Function: hashmap comparator key value …

[R7RS mapping] {scheme.mapping.hash} Creates a new hashmap with the given comparator, whose initial content is provided by key value ….

The comparator argument must be a comparator (see Basic comparators).

The key value … arguments must be even length, alternating keys and values.

(define m (hashmap default-comparator 'a 1 'b 2))

(hashmap-ref m 'a) ⇒ 1
(hashmap-ref m 'b) ⇒ 2
Function: hashmap-unfold p f g seed comparator

[R7RS mapping] {scheme.mapping.hash} Creates a new hashmap, whose content is populated by three procedures, p, f and g, and a seed value seed, as follows.

In each iteration, we have a current seed value, whose initial value is seed.

First, p, a stop predicate, is applied to the current seed value. If it returns true, we stop iteration and returns the new hashmap.

Next, f is applied to the current seed value. It must return two values. The first one is for a key and the second one for the value. We add this pair to the hashmap.

Then, g is applied to the current seed value. The result becomes the seed value of the next iteration. And we iterate.

The following example creates a hashmap that maps ASCII characters to their character codes:

(hashmap-unfold (cut >= <> 128)
                (^c (values (integer->char c) c))
                (cut + <> 1)
                0
                default-comparator)

Predicates

Function: hashmap? obj

[R7RS mapping] {scheme.mapping.hash} Returns #t iff obj is a hashmap object.

Function: hashmap-empty? m

[R7RS mapping] {scheme.mapping.hash} M must be a hashmap. Returns #t if m is empty, #f otherwise. In Gauche, this is same as tree-map-empty? (see Treemaps).

Function: hashmap-contains? m key

[R7RS mapping] {scheme.mapping.hash} M must be a hashmap. Returns #t if m has an entry with key, #f otherwise. In Gauche, this is same as tree-map-exists? (see Treemaps).

Function: hashmap-disjoint? m1 m2

[R7RS mapping] {scheme.mapping.hash} Returns #t iff two hashmaps m1 and m2 have no keys in common. In other words, there’s no such key K that satisfy both (hashmap-contains? m1 K) and (hashmap-contains? m2 K).

Accessors

Function: hashmap-ref m key :optional failure success

[R7RS mapping] {scheme.mapping.hash} Get the value from a hashmap m associated with key, and calls success on the value, and returns its result. If m doesn’t have key, failure is invoked with no arguments and its result is returned. Both success and failure is called in tail context.

When failure is omitted and key is not found, an error is signaled. When success is omitted, identity is assumed.

Function: hashmap-ref/default m key default

[R7RS mapping] {scheme.mapping.hash} Returns the value associated to key from a hashmap m. If m doesn’t have key, default is returned.

Function: hashmap-key-comparator m

[R7RS mapping] {scheme.mapping.hash} Returns a comparator used to compare keys in a hashmap m. See Basic comparators, for the details of comparators.

Updaters

Note that the basic premise of hashmaps srfi is to treat hashmaps as immutable. Each updating operation comes with a purely functional version (without bang) and a linear update version (with bang), but the linear update version may not require to destructively modiy the passed hashmap; it’s merely a hint that it may reuse the argument for the efficiency. You always need to use the returned hashmap as the result of update. If you use linear update versions, you shouldn’t use the passed hashmap afterwards, for there’s no guarantee how the state of the passed hashmap is.

Function: hashmap-adjoin m arg …
Function: hashmap-adjoin! m arg …

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-set m arg …
Function: hashmap-set! m arg …

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-replace m key value
Function: hashmap-replace! m key value

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-delete m key …
Function: hashmap-delete! m key …

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-delete-all m key-list
Function: hashmap-delete-all! m key-list

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-intern m key failure
Function: hashmap-intern! m key failure

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-update m key updater :optional failure success
Function: hashmap-update! m key updater :optional failure success

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-update/default m key updater default
Function: hashmap-update!/default m key updater default

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-pop m :optional failure
Function: hashmap-pop! m :optional failure

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-search m k failure success
Function: hashmap-search! m k failure success

[R7RS mapping] {scheme.mapping.hash}

The whole hashmap

Function: hashmap-size m

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-find pred m failure

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-count pred m

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-any? pred m
Function: hashmap-every? pred m

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-keys m
Function: hashmap-values m

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-entries m

[R7RS mapping] {scheme.mapping.hash}

Mapping and folding

Function: hashmap-map proc comparator m

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-for-each proc m

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-fold kons knil m

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-map->list proc m

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-filter pred m
Function: hashmap-filter! pred m

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-remove pred m
Function: hashmap-remove! pred m

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-partition pred m
Function: hashmap-partition! pred m

[R7RS mapping] {scheme.mapping.hash}

Copying and conversion

Function: hashmap-copy m

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap->alist m

[R7RS mapping] {scheme.mapping.hash}

Function: alist->hashmap comparator alist

[R7RS mapping] {scheme.mapping.hash}

Function: alist->hashmap! m alist

[R7RS mapping] {scheme.mapping.hash}

Subhashmaps

Function: hashmap=? comparator m1 m2 …

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap<? comparator m1 m2 …
Function: hashmap<=? comparator m1 m2 …
Function: hashmap>? comparator m1 m2 …
Function: hashmap>=? comparator m1 m2 …

[R7RS mapping] {scheme.mapping.hash}

Set operations

Function: hashmap-union m1 m2 …
Function: hashmap-union! m1 m2 …

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-intersection m1 m2 …
Function: hashmap-intersection! m1 m2 …

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-difference m1 m2 …
Function: hashmap-difference! m1 m2 …

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-xor m1 m2 …
Function: hashmap-xor! m1 m2 …

[R7RS mapping] {scheme.mapping.hash}

Comparators

Function: make-hashmap-comparator comparator

[R7RS mapping] {scheme.mapping.hash}

Variable: hashmap-comparator

[R7RS mapping] {scheme.mapping.hash}


Next: , Previous: , Up: R7RS large   [Contents][Index]

10.3.18 scheme.division - R7RS integer division

Module: scheme.division

This module provides a comprehensive set of integer division operators.

Quotient and remainder in integer divisions can be defined in multiple ways, when you consider the choice of sign of the result with regard to the operands. Gauche has builtin procedures in several flavors: R5RS quotient, remainder and modulo, R6RS div, mod, div0 and mod0, and R7RS floor-quotient, floor-remainder, floor/, truncate-quotient, truncate-remainder, truncate/.

This module complements R7RS procedures, by adding ceiling, round, euclidean and balanced variants.

The following procedures are in scheme.division but built-in in Gauche (see Arithmetics).

floor-quotient     floor-remainder    floor/
truncate-quotient  truncate-remainder truncate/
Function: ceiling-quotient n d
Function: ceiling-remainder n d
Function: ceiling/ n d

[R7RS division] {scheme.division}

ceiling-quotient = ceiling(n / d)
ceiling-remainder = n - d * ceiling-quotient
ceiling/ = values(ceiling-quotient, ceiling-remainder)
Function: round-quotient n d
Function: round-remainder n d
Function: round/ n d

[R7RS division] {scheme.division}

round-quotient = round(n/d)
round-remainder = n - d * round-quotient
round/ = values(round-quotient, round-remainder)
Function: euclidean-quotient n d
Function: euclidean-remainder n d
Function: euclidean/ n d

[R7RS division] {scheme.division}

euclidean-quotient = floor(n / d)   if d > 0
                     ceiling(n / d) if d < 0
euclidean-remainder = n - d * euclidean-quotient
euclidean/ = values(euclidean-quotient, euclidean-remainder)

The Eclidean variant satisfies a property 0 <= remainder < abs(d). These are the same as R6RS’s div, mod, and div-and-mod, except that they accept non-integers (see Arithmetics)

Function: balanced-quotient n d
Function: balanced-remainder n d
Function: balanced/ n d

[R7RS division] {scheme.division}

balanced-quotient = roundup(n / d)
balanced-remainder = n - d * balanced-quotient
balanced/ = values(balanced-quotient, balanced-remainder)
  where roundup(x) is  ceiling(x) if x - floor(x) <= 0.5
                   and floor(x)   if x - floor(x) > 0.5

The balanced variant satisfies a property -abs(d/2) <= remainder < abs(d/2). These are the same as R6RS’s div0, mod0, and div0-and-mod0, except that they accept non-integers (see Arithmetics).


Next: , Previous: , Up: R7RS large   [Contents][Index]

10.3.19 scheme.bitwise - R7RS bitwise operations

Module: scheme.bitwise

This module provides comprehensive bitwise operations. Originally it was srfi-151. It is mostly a superset of srfi-60, with some change of names for the consistency and the compatibility (see Integers as bits). We keep srfi-60 for legacy code, while recommend this module to be used in the new code.

The following procedures are Gauche built-in. See Basic bitwise operations, for the description.

integer-length    copy-bit          bit-field

Basic operations

Function: bitwise-not n

[R7RS bitwise] {scheme.bitwise} Returns the bitwise complement of n. Same as builtin lognot (see Basic bitwise operations).

Function: bitwise-and n …
Function: bitwise-ior n …
Function: bitwise-xor n …
Function: bitwise-eqv n …

[R7RS bitwise] {scheme.bitwise} When no arguments are given, these procedures returns -1, 0, 0 and -1, respectively. With one arguments, they return the argument as is. With two arguments, they return bitwise and, ior, xor, and eqv (complement of xor). With three or more arguments, they apply binary operations associaively, that is,

(bitwise-xor a b c)
 ≡ (bitwise-xor a (bitwise-xor b c))
 ≡ (bitwise-xor (bitwise-xor a b) c)

Be careful that multi-argument bitwise-eqv does not produce bit 1 everywhere that all the argument’s bit agree.

The first three procedures are the same as built-in logand, logior and logxor, respectively (see Basic bitwise operations).

Function: bitwise-nand n0 n1
Function: bitwise-nor n0 n1
Function: bitwise-andc1 n0 n1
Function: bitwise-andc2 n0 n1
Function: bitwise-orc1 n0 n1
Function: bitwise-orc2 n0 n1

[R7RS bitwise] {scheme.bitwise} These operations are not associative.

nand n0 n1   ≡  (NOT (AND n0 n1))
nor n0 n1    ≡  (NOT (OR n0 n1))
andc1 n0 n1  ≡  (AND (NOT n0) n1)
andc2 n0 n1  ≡  (AND n0 (NOT n1))
orc1 n0 n1   ≡  (OR (NOT n0) n1)
orc2 n0 n1   ≡  (OR n0 (NOT n1))

Integer operations

Function: arithmetic-shift n count

[R7RS bitwise] {scheme.bitwise} Shift n for count bits to left; if count is negative, it shifts n to right for -count bits.

Same as builtin ash (see Basic bitwise operations).

Function: bit-count n

[R7RS bitwise] {scheme.bitwise} If n is positive, returns the number of 1’s in n. If n is negative, returns the number of 0’s in n.

Same as builtin logcount (see Basic bitwise operations).

Function: bitwise-if mask n0 n1

[R7RS bitwise] {scheme.bitwise} Returns integer, whose n-th bit is taken as follows: If the n-th bit of mask is 1, the n-th bit of n0; otherwise, the n-th bit of n1.

(bitwise-if #b10101100 #b00110101 #b11001010)
 ⇒ #b01100110

Single-bit operations

Function: bit-set? index n

[R7RS bitwise] {scheme.bitwise} Returns #t or #f if index-th bit (counted from LSB) of n is 1 or 0, respectively.

Same as built-in logbit? (see Basic bitwise operations).

Function: bit-swap index1 index2 n

[R7RS bitwise] {scheme.bitwise} Returns an integer with index1-th bit and index2-th bit are swapped. Index is counted from LSB.

Function: any-bit-set? mask n
Function: every-bit-set? mask n

[R7RS bitwise] {scheme.bitwise} Returns #t iff any/all bits set in mask are also set in n.

any-bit-set? is the same as built-in logtest, except logtest accepts one or more arguments (see Basic bitwise operations).

Function: first-set-bit n

[R7RS bitwise] {scheme.bitwise} Returns the number of factors of two of integer n; that is, returns a maximum k such that (expt 2 k) divides n without a remainder. It is the same as the index of the least significant 1 in n, hence the alias first-set-bit.

(first-set-bit 0) ⇒ -1   ; edge case
(first-set-bit 1) ⇒ 0
(first-set-bit 2) ⇒ 1
(first-set-bit 15) ⇒ 0
(first-set-bit 16) ⇒ 4

This is equivalent to Gauche’s built-in twos-exponent-factor (see Basic bitwise operations).

Bit field operations

Function: bit-field-any? n start end
Function: bit-field-every? n start end

[R7RS bitwise] {scheme.bitwise} Returns #t iff any/all bits of n from start (inclusive) to end (exclusive) are set.

Function: bit-field-clear n start end
Function: bit-field-set n start end

[R7RS bitwise] {scheme.bitwise} Returns n with the bits from start (inclusive) to end (exclusive) are set to all 0’s/1’s.

Function: bit-field-replace dst src start end

[R7RS bitwise] {scheme.bitwise} Returns dst with the bitfield from start to end are replaced with the least-significant (end-start) bits of src.

(bit-field-replace #b101010 #b010 1 4) ⇒ #b100100

Same as built-in copy-bit-field (see Basic bitwise operations).

Function: bit-field-replace-same dst src start end

[R7RS bitwise] {scheme.bitwise} Returns dst with the bitfield from start to end are replaced with the src’s bitfield from start to end.

(bit-field-replace-same #b111111 #b100100 1 4) ⇒ #b110101
Function: bit-field-rotate n count start end

[R7RS bitwise] {scheme.bitwise} Rotate the region of n between start-th bit (inclusive) and end-th bit (exclusive) by count bits to the left. If count is negative, it rotates to the right by -count bits.

(bit-field-rotate #b110100100010000 -1 5 9)
 ⇒ 26768 ;#b110100010010000

(bit-field-rotate #b110100100010000 1 5 9)
 ⇒ 26672 ;#b110100000110000
Function: bit-field-reverse n start end

[R7RS bitwise] {scheme.bitwise} Reverse the order of bits of n between start-th bit (inclusive) and end-th bit (exclusive).

(bit-field-reverse #b10100111 0 8)
 ⇒ 229 ; #b11100101

Bits conversion

Function: bits->list n :optional len
Function: bits->vector n :optional len

[R7RS bitwise] {scheme.bitwise} Returns a list/vector of booleans of length len, corresponding to each bit in non-negative integer n, LSB-first. When len is omitted, (integer-length n) is used.

(bits->vector #b101101110)
  ⇒ #(#f #t #t #t #f #t #t #f #t)

Note: Srfi-60 has a similar integer->list, but the order of bits is reversed.

Function: list->bits bool-list
Function: vector->bits bool-vector

[R7RS bitwise] {scheme.bitwise} Returns an exact integer formed from boolean values in given list/vector, LSB first. The result will never be negative.

(list->bits '(#f #t #t #t #f #t #t #f #t))
 ⇒ #b101101110

Note: Srfi-60 has a similar list->integer, but the order of bits is reversed.

Function: bits bool …

[R7RS bitwise] {scheme.bitwise} Returns the integer coded by bools, LSB first. The result will never be negative.

(bits #f #t #t #t #f #t #t #f #t)
 ⇒ #b101101110

Note: Srfi-60 has a similar booleans->integer, but the order of bits is reversed.

Fold, unfold and generate

Function: bitwise-fold kons knil n

[R7RS bitwise] {scheme.bitwise} Traverse bits in integer n from LSB to the (integer-length n) bit, applying kons on the bit as boolean and the seed value, whose initial value is given by knil. Returns the last result of kons.

(bitwise-fold cons '() #b10110111)
 ⇒ (#t #f #t #t #f #t #t #t)
Function: bitwise-for-each proc n

[R7RS bitwise] {scheme.bitwise} Applies proc to the bit as boolean in n, from LSB to the (integer-length n) bit. The result is discarded.

Function: bitwise-unfold p f g seed

[R7RS bitwise] {scheme.bitwise} Generates a non-negative integer bit by bit, from LSB to MSB. The seed gives the initial state value. For each iteration, p is applied to the current state value, and if it returns a true value, the iteration ends and bitwise-unfold returns the accumulated bits as an integer. Otherwise, f is applied to the current state value, and its result, coerced to a boolean value, determines the bit value. Then g is applied to the current state value to produce the next state value of the next iteration.

The following expression produces a bitfield of width 100, where n-th bit indicates whether n is prime or not:

(use math.prime)
(bitwise-unfold (cut = 100 <>)
                small-prime?
                (cut + 1 <>)
                0)
Function: make-bitwise-generator n

[R7RS bitwise] {scheme.bitwise} Returns a generator that generates boolean values corresponding to the bits in n, LSB-first. The returned generator is infinite.

This is similar to bits->generator in gauche.generator, except that the generator created by it stops at the integer length of n (see Generators).


Next: , Previous: , Up: R7RS large   [Contents][Index]

10.3.20 scheme.fixnum - R7RS fixnums

Module: scheme.fixnum

This module provides a set of fixnum-specific operations. Originally defined as srfi-143.

A fixnum is a small exact integer that can be handled very efficiently. In Gauche, fixnum is 62bit wide on 64bit platforms, and 30bit wide on 32bit platforms.

Note that these procedures are defined only to work on fixnums, but it is not enforced. If you pass non-fixnum arguments, or the result falls out of range of fixnums, what happens is up to the implementation. Consider these procedures as the way to tell your intentions to the compiler for potential optimizations.

In the current Gauche architecture, generic numeric operators are just as efficient, so most procedures provided in this module are aliases to corresponding operators. However, we might employ some optimizations in future versions.

The procedure fixnum? is built-in, and not explained here. See Numerical predicates.

Variable: fx-width

[R7RS fixnum] {scheme.fixnum} A variable bound to an exact positive integer w, where w is the greatest number such that exact integers between 2^(w-1) - 1 and -2^(w-1) are all fixnums. This value is the same as the built-in procedure fixnum-width returns (see Arithmetics).

In Gauche, it is usually 30 for 32bit platforms, and 62 for 64bit platforms.

Variable: fx-greatest
Variable: fx-least

[R7RS fixnum] {scheme.fixnum} Variables bound to the greatest fixnum and the least fixnum. They are the same as the built-in procedures greatest-fixnum and least-fixnum return, respectively (see Arithmetics).

The following table shows the typical values on Gauche:

Platformfx-greatestfx-least
32bit536,870,911-536,870,912
64bit2,305,843,009,213,693,951-2,305,843,009,213,693,952
Function: fx=? i …
Function: fx<? i …
Function: fx<=? i …
Function: fx>? i …
Function: fx>=? i …

[R7RS fixnum] {scheme.fixnum} These are equivalent to built-in =, <, <=, > and >=, except that you should use these only for fixnums.

Function: fxzero? i
Function: fxpositive? i
Function: fxnegative? i
Function: fxodd? i
Function: fxeven? i

[R7RS fixnum] {scheme.fixnum} These are equivalent to built-in zero?, positive?, negative?, odd? and even?, except that you should use these only for fixnums.

Function: fxmax i j …
Function: fxmin i j …

[R7RS fixnum] {scheme.fixnum} These are equivalent to built-in max and min, except that you should use these only for fixnums.

Function: fx+ i j
Function: fx- i j
Function: fx* i j

[R7RS fixnum] {scheme.fixnum} These are equivalent to built-in +, - and *, except that these take exactly two arguments, and you should use these only for fixnums and when the result fits within fixnum range.

Function: fxneg i

[R7RS fixnum] {scheme.fixnum} This is equivalent to single-argument -, except that you should use this only for fixnums and when the result fits within fixnum range.

Function: fxquotient i j
Function: fxremainder i j
Function: fxabs i
Function: fxsquare i

[R7RS fixnum] {scheme.fixnum} These are equivalent to built-in quotient, remainder, abs and square, except that you should use these only for fixnums and when the result fits within fixnum range.

Function: fxsqrt i

[R7RS fixnum] {scheme.fixnum} This is equivalent to exact-integer-sqrt (not sqrt), except that you should use it only for fixnums. See Arithmetics.

Function: fx+/carry i j k
Function: fx-/carry i j k
Function: fx*/carry i j k

[R7RS fixnum] {scheme.fixnum} These calculates (+ i j k), (- i j k) and (+ (* i j) k), respectively, then split the result to the remainder value R in the fixnum range, and spilled value Q, and return those values. That is, (+ (* Q (expt 2 fx-width)) R) is the result of above calculations. Both Q and R fits in the fixnum range, and - 2^(w-1) <= R < 2^(w-1), where w is fx-width.

(fx*/carry 1845917459 19475917581 4735374)
 ⇒ -942551854601421179 and 8

(+ (* 8 (expt 2 fx-width)) -942551854601421179)
 ⇒ 35950936292817682053

(+ (* 1845917459 19475917581) 4735374)
 ⇒ 35950936292817682053

These are primitives to implement extended-precision integer arithmetic on top of fixnum operations. In Gauche, however, you can just use built-in bignums. We provide these for the compatibility.

Function: fxnot i
Function: fxand i …
Function: fxior i …
Function: fxxor i …
Function: fxarithmetic-shift i count
Function: fxlength i
Function: fxbit-count i
Function: fxcopy-bit index i boolean
Function: fxbit-set? index i
Function: fxbit-field i start end
Function: fxfirst-set-bit i

[R7RS fixnum] {scheme.fixnum} These are equivalent to lognot, logand, logior, logxor, ash, integer-length, logcount, copy-bit, logbit?, bit-field, and twos-exponent-factor respectively, except that you should use these only for fixnums. See Basic bitwise operations.

Function: fxif mask i j
Function: fxbit-field-rotate i start end
Function: fxbit-field-rotate i start end

[R7RS fixnum] {scheme.fixnum} These are equivalent to srfi-60’s bitwise-if, rotate-bit-field and reverse-bit-field, except that you should use these only for fixnums. See Integers as bits.


Previous: , Up: R7RS large   [Contents][Index]

10.3.21 scheme.flonum - R7RS flonum

Module: scheme.flonum

This module provides a set of flonum-specific operations. Originally defined as srfi-144.

In Gauche, a flonum is IEEE 754 double-precision floating point numbers.

Note that these procedures are defined only to work on flonums, but it is not enforced. If you pass non-flonum arguments, the result is undefined. Consider these procedures as the way to tell your intentions to the compiler for potential optimizations.

In the current Gauche architecture, generic numeric operators are just as efficient, so most procedures provided in this module are aliases to corresponding operators. However, we might employ some optimizations in future versions.

The procedure flonum? is built-in, and not explained here. See Numerical predicates.

Constants

We also have a few constants in math.const module (see Mathematic constants).

Constant: fl-e

[R7RS flonum] {scheme.flonum} e.

Constant: fl-1/e

[R7RS flonum] {scheme.flonum} (/ e).

Constant: fl-e-2

[R7RS flonum] {scheme.flonum} (square e).

Constant: fl-e-pi/4

[R7RS flonum] {scheme.flonum} (expt e (/ pi 4)).

Constant: fl-log2-e

[R7RS flonum] {scheme.flonum} (log2 e). (Same as (/ (log 2))).

Constant: fl-log10-e

[R7RS flonum] {scheme.flonum} (log10 e). (Same as (/ (log 10))).

Constant: fl-log-2

[R7RS flonum] {scheme.flonum} (log 2).

Constant: fl-1/log-2

[R7RS flonum] {scheme.flonum} (/ (log 2)). (Same as (log2 e)).

Constant: fl-log-3

[R7RS flonum] {scheme.flonum} (log 3).

Constant: fl-log-pi

[R7RS flonum] {scheme.flonum} (log pi).

Constant: fl-log-10

[R7RS flonum] {scheme.flonum} (log 10).

Constant: fl-1/log-10

[R7RS flonum] {scheme.flonum} (/ (log 10)). (Same as (log10 e)).

Constant: fl-pi

[R7RS flonum] {scheme.flonum} pi.

Constant: fl-1/pi

[R7RS flonum] {scheme.flonum} (/ pi).

Constant: fl-2pi

[R7RS flonum] {scheme.flonum} (* 2 pi).

Constant: fl-pi/2

[R7RS flonum] {scheme.flonum} (/ pi 2).

Constant: fl-pi/4

[R7RS flonum] {scheme.flonum} (/ pi 4).

Constant: fl-pi-squared

[R7RS flonum] {scheme.flonum} (square pi).

Constant: fl-degree

[R7RS flonum] {scheme.flonum} (/ pi 180).

Constant: fl-2/pi

[R7RS flonum] {scheme.flonum} (/ 2 pi).

Constant: fl-2/sqrt-pi

[R7RS flonum] {scheme.flonum} (/ 2 (sqrt pi)).

Constant: fl-sqrt-2

(sqrt 2).

Constant: fl-sqrt-3

[R7RS flonum] {scheme.flonum} (sqrt 3).

Constant: fl-sqrt-5

[R7RS flonum] {scheme.flonum} (sqrt 5).

Constant: fl-sqrt-10

[R7RS flonum] {scheme.flonum} (sqrt 10).

Constant: fl-1/sqrt-2

[R7RS flonum] {scheme.flonum} (/ (sqrt 2)).

Constant: fl-cbrt-2

[R7RS flonum] {scheme.flonum} (expt 2 1/3).

Constant: fl-cbrt-3

[R7RS flonum] {scheme.flonum} (expt 3 1/3).

Constant: fl-4thrt-2

[R7RS flonum] {scheme.flonum} (expt 2 1/4).

Constant: fl-phi

[R7RS flonum] {scheme.flonum} (/ (+ 1 (sqrt 5)) 2).

Constant: fl-log-phi

[R7RS flonum] {scheme.flonum} (log fl-phi).

Constant: fl-1/log-phi

[R7RS flonum] {scheme.flonum} (/ (log fl-phi)).

Constant: fl-euler

[R7RS flonum] {scheme.flonum} Euler’s constant.

Constant: fl-e-euler

[R7RS flonum] {scheme.flonum} (exp fl-euler)

Constant: fl-sin-1

[R7RS flonum] {scheme.flonum} (sin 1)

Constant: fl-cos-1

[R7RS flonum] {scheme.flonum} (cos 1)

Constant: fl-gamma-1/2

[R7RS flonum] {scheme.flonum} (gamma 1/2)

Constant: fl-gamma-1/3

[R7RS flonum] {scheme.flonum} (gamma 1/3)

Constant: fl-gamma-2/3

[R7RS flonum] {scheme.flonum} (gamma 2/3)

Constant: fl-gamma-1/3

[R7RS flonum] {scheme.flonum} (gamma 1/3)

Constant: fl-greatest
Constant: fl-least

[R7RS flonum] {scheme.flonum} Bound to the largest/smallest positive finite flonum.

The latter is the same as (flonum-min-denormalized) in Gauche (see Numerical comparison).

Constant: fl-epsilon

[R7RS flonum] {scheme.flonum} The same as (flonum-epsilon) in Gauche (see Numerical comparison).

Constant: fl-fast-fl+*

[R7RS flonum] {scheme.flonum} If this is #t, (fl+* x y z) executes as fast as, or faster than, (fl+ (fl* x y) z). If not, #f.

Constant: fl-integer-exponent-zero
Constant: fl-integer-exponent-nan

[R7RS flonum] {scheme.flonum} These are exact integer values returned in special occasion from flinteger-exponent. The values themselves don’t mean much; they’re to be compared with the result of flinteger-exponent.

If its argument is 0, flinteger-exponent returns fl-integer-exponent-zero. If its argument is +nan.0, flinteger-exponent returns fl-integer-exponent-nan.

Constructors

Function: flonum number

[R7RS flonum] {scheme.flonum} Returns a flonum that’s equal to or (if there’s no equivalent flnoum) the closest to number.

If number is not a real number, +nan.0 is returned. (Note: srfi-144 recommends it, but a conformant implementation may signal an error in such case. Portable code shouldn’t rely on this behavior.)

Function: fladjacent x y

[R7RS flonum] {scheme.flonum} Returns a flonum adjacent to x in the direction of y. If x = y, x is returned.

(fladjacent 1.0 2.0) ⇒ 1.0000000000000002
(fladjacent 1.0 0.0) ⇒ 0.9999999999999999
Function: flcopysign x y

[R7RS flonum] {scheme.flonum} Returns a flonum whose absolute value is (abs x) and whose sign is the sign of y.

Function: make-flonum x n

[R7RS flonum] {scheme.flonum} Returns a flonum (* x (expt 2 n)). It is the same as ldexp (see Numerical conversions).

Accessors

Function: flinteger-fraction x

[R7RS flonum] {scheme.flonum} Returns two flnoums, the integral part of x and the fractional part of x. Same as modf (see Numerical conversions).

If x is +inf.0, +inf.0 and 0.0 is returned. If x is -inf.0, -inf.0 and -0.0 is returned. If x is +nan.0, +nan.0 and +nan.0 is returned. (These corner cases are not explicit in srfi-144, but follows the POSIX specification of modf.)

(flinteger-fraction fl-pi)
 ⇒ 3.0 and 0.14159265358979312
Function: flexponent x

[R7RS flonum] {scheme.flonum} Returns the exponent part of x as a flnoum. If x is a non-zero finite value, the result is an integer.

If x is zero, -inf.0 is returned. If x is +inf.0 or -inf.0, +inf.0 is returned.

(flexponent 1.0)    ⇒ 0.0
(flexponent 1024.0) ⇒ 10.0
(flexponent 0.01)   ⇒ -7.0
(flexponent fl-least) ⇒ -1074.0
Function: flinteger-exponent x

[R7RS flonum] {scheme.flonum} Returns the same as flexponent but as an exact integer.

If x is zero, the value of fl-integer-exponent-zero is returned. If x is +inf.0 or -inf.0, a large implementation-dependent exact integer (usually it’s so large that (ldexp 1 (flinteger-exponent +inf.0)) becomes +inf.0) is returned. If x is +nan.0, the value of fl-integer-exponent-nan is returned.

Function: flnormalized-fraction-exponent x

[R7RS flonum] {scheme.flonum} Returns two values, a normalized mantissa of x with the same sign as x as a flonum, and an exact integer exponent of x. If it returns a value y and n, x = (* y (expt 2 n)) and x = (ldexp y n). This is the same as frexp (see Numerical conversions).

If x is non-zero finite value, the first value falls between 0.5 (inclusive) and 1.0 (exclusive). The corner cases are not explicit in srfi-144, but Gauche follows frexp: If x is (minus) zero, it returns (minus) zero and 0; if x is infinity, it returns infinity (of the same sign) and 0; if x is +nan.0, it returns +nan.0 and 0.

(flnormalized-fraction-exponent 12345.6789)
  ⇒ 0.7535204406738282 and 14
(make-flonum 0.7535204406738282 14)
  ⇒ 12345.6789
Function: flsign-bit x

[R7RS flonum] {scheme.flonum} Returns 0 if x is positive or 0.0, and 1 if it is negative (including -0.0). (flsign-bit +nan.0) is implementation-dependent.

There’s also flsgn, if you need sign instead of a bit value.

Predicates

(Note: flonum? is built-in; see Numerical predicates).

Function: fl=? x y z …
Function: fl<? x y z …
Function: fl>? x y z …
Function: fl<=? x y z …
Function: fl>=? x y z …

[R7RS flonum] {scheme.flonum} Flonum specific version of numerical comparison predicates =, <, >, <= and >=, respectively.

Currently these are just an alias of the generic numerical comparison predicates; hence they don’t reject when you pass non-flonum arguments, but doing so is not portable. These are to give compilers hints that you are passing flonums so that it can optimize.

Note that -0.0 and 0.0 are the same in terms of these predicates, e.g. (fl<? -0.0 0.0) is #f.

If a +nan.0 is passed to any of the arguments, these predicates returns #f.

Function: flunordered? x y

[R7RS flonum] {scheme.flonum} Returns #t iff at least one of x or y is a +nan.0.

Function: flinteger? x

[R7RS flonum] {scheme.flonum} Returns #t if x is an integral flonum, #f otherwise.

Function: flzero? x
Function: flpositive? x
Function: flnevative? x

[R7RS flonum] {scheme.flonum} Flonum-specific version of zero?, positive? and negative?. Note that (flnegative? -0.0) is #f. You need flsign-bit or flsgn to distinguish negative zero from zero.

Function: flodd? x
Function: fleven? x

[R7RS flonum] {scheme.flonum} Flonum-specific version of odd? and even?. An error is thrown if x is not an integer.

Function: flfinite? x
Function: flinfinite? x
Function: flnan? x

[R7RS flonum] {scheme.flonum} Flonum-specific version of finite?, infinite? and nan? (see Numerical predicates).

Function: flnormalized? x
Function: fldenormalized? x

[R7RS flonum] {scheme.flonum} Returns #t iff x is a normalized/denormalized flonum, respectively.

Arithmetic

Function: flmax x …
Function: flmin x …

[R7RS flonum] {scheme.flonum} Flonum-specific version of min and max, except that these can take no arguments, in which case -inf.0 and +inf.0 are returned, respectively.

Note that we don’t check whether the arguments are flonums or not, but passing non-flonums are not portable.

Function: fl+ x …
Function: fl* x …

[R7RS flonum] {scheme.flonum} Flonum-specific version of +. and *. (see Arithmetics).

Note that we don’t check whether the arguments are flonums or not, but passing non-flonums is not portable.

Function: fl+* x y z

[R7RS flonum] {scheme.flonum} Returns (+ (* x y) z), but (potentially) faster, and more accurately. It calls C99 fma function internally. “More accurately” means that calculation is done in a single step, with rounding once at the end.

Note: As of release of 0.9.8, MinGW implementation of fma seems to produce slightly off value occasionally, as if it is calculated with the two steps (rounding after multiplication).

Function: fl- x y …
Function: fl- x y …

[R7RS flonum] {scheme.flonum} Flonum-specific version of -. and /. (see Arithmetics).

Note that we don’t check whether the arguments are flonums or not, but passing non-flonums is not portable.

Function: flabs x

[R7RS flonum] {scheme.flonum} Flonum-specific version of abs (see Arithmetics).

Note that we don’t check whether the argument is a flonum or not, but passing non-flonum is not portable.

Function: flabsdiff x y

[R7RS flonum] {scheme.flonum} Returns (abs (- x y)).

Note that we don’t check whether the arguments are flonums or not, but passing non-flonum is not portable.

Function: flposdiff

[R7RS flonum] {scheme.flonum} Returns (max (- x y) 0).

Note that we don’t check whether the arguments are flonums or not, but passing non-flonum is not portable.

Function: flsgn x

[R7RS flonum] {scheme.flonum} Returns 1.0 if x’s sign bit is 0 (zero or positive), -1.0 if it’s 1 (negative). Same as (flcopysign 1.0 x), or (if (zero? (flsign-bit x)) 1.0 -1.0). Note that (flsgn 0.0) is 1.0, while (flsgn -0.0) is -1.0. The result of passing +nan.0 is implementation-dependent, reflecting the sign bit of underlying representation; it returns either 1.0 or -1.0 but you can’t count on which.

To extract the sign bit, instead of obtaining a signed flonum, you can use flsign-bit.

Function: flnumerator x
Function: fldenominator x

[R7RS flonum] {scheme.flonum} Flonum-specific version of numerator and denominator (see Arithmetics).

For infinity and zero, denominator is 1.0.

Note that we don’t check whether the arguments are flonums or not, but passing non-flonum is not portable.

Function: flfloor x
Function: flceiling x
Function: flround x
Function: fltruncate x

[R7RS flonum] {scheme.flonum} Flonum-specific version of floor, ceiling, round and truncate (see Arithmetics).

Note that we don’t check whether the arguments are flonums or not, but passing non-flonum is not portable.

Exponents and logarithms

Function: flexp x

[R7RS flonum] {scheme.flonum} Flonum-specific version of exp (see Arithmetics). Returns (expt fl-e x).

Function: flexp2 x

[R7RS flonum] {scheme.flonum} Returns (expt 2 x)

Function: flexp-1 x

[R7RS flonum] {scheme.flonum} Returns (- 1 (expt fl-e x)), but is much more accurate when x is small. We all C’s expm1 internally.

Function: flsquare x

[R7RS flonum] {scheme.flonum} Returns (*. x x) (see Arithmetics)

Function: flsqrt x

[R7RS flonum] {scheme.flonum} Flonum-specific version of sqrt.

Function: flcbrt x

[R7RS flonum] {scheme.flonum} Returns cubic root of a flonum x.

Function: flhypot x y

[R7RS flonum] {scheme.flonum} Calculates (sqrt (* x x) (* y y)), with avoiding overflow or underflow during the intermediate steps.

Function: flexpt x y

[R7RS flonum] {scheme.flonum} Flonum-specific version of expt (see Arithmetics).

Function: fllog x

[R7RS flonum] {scheme.flonum} Flonum-specific version of log (see Arithmetics).

Function: fllog1+ x

[R7RS flonum] {scheme.flonum} Returns (log (+ x 1)), but is more accurate than log when x is near zero.

Function: fllog2 x
Function: fllog10 x

[R7RS flonum] {scheme.flonum} Returns base-2 and base-10 logarithm of a flonum x, respectively.

Function: make-fllog-base x

[R7RS flonum] {scheme.flonum} Returns a procedure that calculates base-x logarithm. An error is signalled if x isn’t a rela number greater than 1.0.

Trigonometric functions

Function: flsin x
Function: flcos x
Function: fltan x
Function: flasin x
Function: flacos x
Function: flatan x
Function: flatan y x
Function: flsinh x
Function: flcosh x
Function: fltanh x
Function: flasinh x
Function: flacosh x
Function: flatanh x

[R7RS flonum] {scheme.flonum} Flonum-specific version of sin, cos, tan, asin, acos, sinh, cosh, tanh, asinh, acosh, and atanh, respectively (see Arithmetics).

Note that flatan can take one or two arguments; if two arguments are passed, it calculates (atan (/ y x).

Integer division

Function: flquotient x y

[R7RS flonum] {scheme.flonum} Returns (fltruncate (fl/ x y)). The result is always integer flonum, but x and y doesn’t need to be integers.

(flquotient 14.0 4.0)  ⇒ 3.0
(flquotient -14.0 4.0) ⇒ -3.0
(flquotient 14.0 2.5)  ⇒ 5.0
(flquotient -14.2 2.8) ⇒ -5.0
Function: flremainder x y

[R7RS flonum] {scheme.flonum} Returns (- x (* y (flquotient x y))).

(flquotient 14.0 4.0)  ⇒ 2.0
(flquotient -14.0 4.0) ⇒ -2.0
(flquotient 14.0 2.5)  ⇒ 1.5
(flquotient -14.2 2.8) ⇒ -0.1999999999999993 ; inexact calculation
Function: flremquo x y

[R7RS flonum] {scheme.flonum} Returns two values:

This corresponds to C99’s remquo.

This function is useful to reduce the input for the periodic functions with symmetries.

Special functions

Function: flgamma x

[R7RS flonum] {scheme.flonum} Computes the value of gamma function for x. When x is integer, it is the same as the factorial of x-1.

This is same as Gauche’s built-in gamma (see Arithmetics).

Function: flloggamma x

[R7RS flonum] {scheme.flonum} Returns two values, (log (abs (flgamma x))) and the sign of (flgamma x) as 1.0 if it is positive and -1.0 if it is negative.

The first value is calculated by Gauche’s built-in lgamma (see Arithmetics). It’s more accurate than using gamma then calling log. The second value is +nan.0 when x is -inf.0 or +nan.0.

Function: flfirst-bessel n x

[R7RS flonum] {scheme.flonum} Returns the n-th order Bessel function of the first kind.

Function: flsecond-bessel n x

[R7RS flonum] {scheme.flonum} Returns the n-th order Bessel function of the second kind.

Function: flerf x

[R7RS flonum] {scheme.flonum} Returns the error function erf(x).

Function: flerfc x

[R7RS flonum] {scheme.flonum} Returns the complementary error function, 1 - erf(x).


Previous: , Up: R7RS large   [Contents][Index]