3 API Documentation
3.1 Generic Collections and Sequences
Generic sequences are the bulk of this library, providing a uniform interface for interacting with collections. Sequences are distinct from Racket sequences, which are a different, much more ad-hoc concept.
A generic collection is any structure that can contain values, while a generic sequence represents a sequence of ordered values.
3.1.1 Collections
value
The following built-in datatypes have implementations for gen:collection:
immutable hash tables
immutable vectors
immutable hash sets
immutable dictionaries
Examples: | ||||
|
procedure
(collection? v) → boolean?
v : any/c
3.1.1.1 Generic Methods
procedure
(conj coll item) → collection?
coll : collection? item : any/c
If extend is implemented but not conj, an implementation will automatically be provided.
Examples: | ||||||||
|
procedure
(extend a b) → collection?
a : collection? b : sequence?
If conj is implemented but not extend, an implementation will automatically be provided.
Examples: | ||||||||
|
3.1.1.2 Derived Functions
procedure
(conj* coll item ...) → collection?
coll : collection? item : any/c
Example: | ||
|
procedure
(extend* base extension ...) → collection?
base : collection? extension : sequence?
Example: | ||
|
3.1.2 Sequences
value
The following built-in datatypes have implementations for gen:sequence:
immutable hash tables
immutable vectors
immutable hash sets
immutable dictionaries
Example: | ||
|
3.1.2.1 Generic Methods
All implementations of gen:sequence are required to implement this method, unless they also implement gen:countable.
Examples: | ||||||||
|
This method is optional if an implementation of nth is provided.
Examples: | ||||||
|
All implementations of gen:sequence are required to implement this method.
Examples: | ||||||||
|
procedure
seq : sequence? index : exact-nonnegative-integer?
If seq also implements gen:countable and is known-finite?, bounds checking will automatically be provided, and a exn:fail:contract error will be raised if index is out of range.
This method is optional if an implementation of first is provided.
Examples: | ||||
|
procedure
seq : sequence? index : exact-nonnegative-integer? value : any/c
Example: | ||
|
procedure
(update-nth seq index proc) → sequence?
seq : sequence? index : exact-nonnegative-integer? proc : (any/c . -> . any/c)
Example: | ||
|
procedure
seq : sequence? index : exact-nonnegative-integer? value : any/c
Example: | ||
|
procedure
(update-nth* seq index proc ... ...) → sequence?
seq : sequence? index : exact-nonnegative-integer? proc : (any/c . -> . any/c)
Example: | ||
|
Examples: | ||||||
|
procedure
(sequence->collection seq) → collection?
seq : sequence?
Beware that the fallback collection returned by this function can be very slow if repeatedly conj’d upon. However, since most sequences are also collections, it can also be much, much faster than copying the sequence into a collection type with extend. Therefore, it is recommended that general-purpose sequences which are not collections always implement a performant version of sequence->collection.
Examples: | ||||||||
|
procedure
(random-access? seq) → boolean?
seq : sequence?
This can be used as a heuristic to determine what sort of algorithm to use when operating over generic sequences. For example, if a sequence is determined to be random access, the default implementation for update-nth will use nth and set-nth. Otherwise, it will lazily loop.
3.1.2.2 Derived Functions
Examples: | ||||||
|
procedure
proc : procedure? arg : any/c args : sequence? kw-arg : any/c
Examples: | ||||||
|
In many cases, it may be preferably to use extend or extend*, which may also provide better performance, especially for homogenous sequence types.
Examples: | ||||||
|
procedure
seq : sequence? seqs : (sequenceof sequence?)
Examples: | ||||||
|
Examples: | ||||
|
Examples: | ||||
|
procedure
start : exact-nonnegative-integer? = 0
Examples: | ||||
|
procedure
end : number? (range start end [step]) → stream? start : number? end : number? step : number? = 1
Examples: | ||||
|
procedure
(randoms [rand-gen])
→ (sequenceof (and/c real? inexact? (>/c 0) (</c 1)))
rand-gen : pseudo-random-generator? = (make-pseudo-random-generator) (randoms k [rand-gen]) → (sequenceof exact-nonnegative-integer?) k : (integer-in 1 4294967087)
rand-gen : pseudo-random-generator? = (make-pseudo-random-generator)
Examples: | ||||||||||||||
|
procedure
n : exact-nonnegative-integer? seq : sequence?
Example: | ||
|
procedure
n : exact-nonnegative-integer? seq : sequence?
Example: | ||
|
procedure
(subsequence seq start end) → sequence?
seq : sequence? start : exact-nonnegative-integer? end : exact-nonnegative-integer?
Example: | ||
|
procedure
(subsequence* seq start len) → sequence?
seq : sequence? start : exact-nonnegative-integer? len : exact-nonnegative-integer?
Example: | ||
|
Examples: | ||||
|
procedure
proc : procedure? seq : sequence?
Examples: | |||||||||||
|
procedure
proc : procedure? init : any/c seq : sequence?
Unlike base:foldl, the accumulator argument is always provided to proc first, not last.
Examples: | ||||
|
procedure
proc : procedure? seq : sequence?
procedure
proc : procedure? seq : sequence?
Examples: | ||||||
|
procedure
proc : procedure? seq : sequence?
Examples: | ||||||
|
Examples: | ||||||||
|
procedure
(chunk n seq) → (sequenceof sequence?)
n : exact-positive-integer? seq : sequence?
Example: | ||
|
procedure
(chunk* n seq) → (sequenceof sequence?)
n : exact-positive-integer? seq : sequence?
Example: | |||||||||||||||
|
procedure
(append-map f seq ...+) → sequence?
f : procedure? seq : sequence?
Example: | ||
|
procedure
(cartesian-product seq ...) → (sequenceof sequence?)
seq : sequence?
Examples: | ||||||||||||||||||||||||
|
procedure
seq : sequence?
procedure
seq : sequence?
procedure
seq : sequence?
procedure
seq : sequence?
procedure
seq : sequence?
procedure
seq : sequence?
procedure
seq : sequence?
procedure
seq : sequence?
procedure
seq : sequence?
Examples: | ||||||
|
Examples: | |||||||||||
|
syntax
(for/sequence (for-clause ...) body-or-break ... body)
syntax
(for*/sequence (for-clause ...) body-or-break ... body)
The for*/sequence form is the same as for/sequence but with the implicit nesting behavior of for*.
Example: | ||||||
|
syntax
(for/sequence/derived name-id (for-clause ...) body-or-break ... body)
syntax
(for*/sequence/derived name-id (for-clause ...) body-or-break ... body)
Examples: | |||||||||||||||
|
procedure
(sequence->list seq) → list?
seq : sequence?
If seq is infinite, then this function will not terminate, and it will infinitely allocate memory until it is exhausted.
Examples: | ||||
|
procedure
(sequence->list* seq) → list?
seq : sequence?
If seq or any of its subsequences are infinite, then this function will not terminate, and it will infinitely allocate memory until it is exhausted.
Examples: | ||||
|
procedure
(sequence->string seq) → (and/c string? sequence?)
seq : (sequenceof char?)
procedure
(sequence->bytes seq) → (and/c bytes? sequence?)
seq : (sequenceof byte?)
procedure
(generate-sequence gen) → sequence?
gen : generator?
Example: | |||||||
|
3.2 General-Purpose Interfaces
3.2.1 Countable Collections
Lots of data structures may be considered countable—that is, they have a discrete number of elements. The gen:countable interface only provides a single function, length.
value
The following built-in datatypes have implementations for gen:countable:
For streams, if the argument is infinite, then length does not terminate.
Examples: | ||||||||||||||||||
|
procedure
(countable? v) → boolean?
v : any/c
procedure
(length countable) → exact-nonnegative-integer?
countable : countable?
procedure
(known-finite? countable) → boolean?
countable : countable?
If no implementation for known-finite? is provided, it will always return #f.
Examples: | ||||||
|
3.2.2 Indexable Collections
Data structures are indexable if they provide any sort of indexed data.
value
Be careful when using ref with generic sequences. If numeric indexing is your intention, use nth instead, since ref and nth may have different behaviors on the same sequence. Notably, ref on association lists uses dict-ref, not list-ref.
All generic sequences are also indexable, so implementations of gen:sequence do not need to implement gen:indexable if they provide simply key/value mappings based on index. Additionally, mutable hash tables, mutable vectors, and dictionaries are also indexable.
Examples: | ||||||||||||
|
procedure
(indexable? v) → boolean?
v : any/c
procedure
collection : indexable? index : any/c
procedure
collection : indexable? index : any/c value : any/c
3.2.3 Using sequences with match
If pat ... splicing patterns are used in a non-final position, the sequence will be forced, and if the sequence is not finite, the match will not terminate. Otherwise, the other elements of the sequence not matched will not be forced, including a possible lazy tail.
Examples: | ||||||||||||
|
3.2.4 Contracts on Collections
procedure
(sequenceof ctc [#:chaperone? chaperone?]) → contract?
ctc : contract? chaperone? : any/c = #f
If chaperone? is non-#f, then the result will always be a chaperone-contract?, and ctc must also be a chaperone-contract?. If chaperone? is #f, the result will always be a simple contract?.
For most sequence types, when a sequenceof contract is applied to a sequence, the result is always equal? to its input. However, for a small set of sequences, such as hash tables, strings, and byte strings, the result will be an entirely disparate type of sequence. This behavior is only supported for non-chaperone contracts, so if chaperone? is non-#f, then those sequences will not be permitted by the contract.