3.14 Sequences

► |  | Reference: Racket

1 | Language Model
2 | Syntactic Forms
3 | Datatypes
4 | Structures
5 | Classes and Objects
6 | Units
7 | Contracts
8 | Pattern Matching
9 | Control Flow
10 | Concurrency
11 | Macros
12 | Input and Output
13 | Reflection and Security
14 | Operating System
15 | Memory Management
16 | Unsafe Operations
17 | Running Racket
| Bibliography
| Index

▼ | 3 | Datatypes

3.1 | Booleans and Equality
3.2 | Numbers
3.3 | Strings
3.4 | Byte Strings
3.5 | Characters
3.6 | Symbols
3.7 | Regular Expressions
3.8 | Keywords
3.9 | Pairs and Lists
3.10 | Mutable Pairs and Lists
3.11 | Vectors
3.12 | Boxes
3.13 | Hash Tables
3.14 | Sequences
3.15 | Dictionaries
3.16 | Sets
3.17 | Procedures
3.18 | Void and Undefined

► | 3.14 | Sequences

3.14.1 | Sequence Predicate and Constructors
3.14.2 | Sequence Generators
3.14.3 | Iterator Generators

On this page:

3.14.1`` Sequence Predicate and Constructors
sequence?
empty-seqn
seqn->list
seqn-cons
seqn-first
seqn-rest
seqn-length
seqn-ref
seqn-tail
seqn-append
seqn-map
seqn-andmap
seqn-ormap
seqn-for-each
seqn-fold
seqn-filter
seqn-add-between
seqn-count
in-range
in-naturals
in-list
in-mlist
in-vector
in-string
in-bytes
in-port
in-input-port-bytes
in-input-port-chars
in-lines
in-bytes-lines
in-hash
in-hash-keys
in-hash-values
in-hash-pairs
in-directory
in-producer
in-value
in-indexed
in-sequences
in-cycle
in-parallel
stop-before
stop-after
make-do-sequence
prop: sequence
3.14.2`` Sequence Generators
sequence-generate
3.14.3`` Iterator Generators
generator
infinite-generator
in-generator
yield
generator-state
sequence->generator
sequence->repeated-generator

top← prev up next →

#### 3.14`` Sequences

> > > Sequence Constructors in Guide: Racket introduces sequences.

A sequence encapsulates an ordered stream of values. The elements of a sequence can be extracted with one of the for syntactic forms or with the procedures returned by sequence-generate.

The sequence datatype overlaps with many other datatypes. Among built-in datatypes, the sequence datatype includes the following:

- strings (see Strings)

- byte strings (see Byte Strings)

- lists (see Pairs and Lists)

- mutable lists (see Mutable Pairs and Lists)

- vectors (see Vectors)

- hash tables (see Hash Tables)

- dictionaries (see Dictionaries)

- sets (see Sets)

- input ports (see Ports)

In addition, make-do-sequence creates a sequence given a thunk that returns procedures to implement a generator, and the prop:sequence property can be associated with a structure type.

For most sequence types, extracting elements from a sequence has no side-effect on the original sequence value; for example, extracting the sequence of elements from a list does not change the list. For other sequence types, each extraction implies a side effect; for example, extracting the sequence of bytes from a port cause the bytes to be read from the port.

Individual elements of a sequence typically correspond to single values, but an element may also correspond to multiple values. For example, a hash table generates two values – a key and its value – for each element in the sequence.

##### 3.14.1`` Sequence Predicate and Constructors

( sequence? v) → boolean?
v : any/c

Return #t if v can be used as a sequence, #f otherwise.

empty-seqn : sequence?

A sequence with no elements.

( seqn->list s) → list?
s : sequence?

Returns a list whose elements are the elements of the s, which must be a one-valued sequence. If s is infinite, this function does not terminate.

( seqn-cons v ... s) → sequence?
v : any/c
s : sequence?

Returns a sequence whose first element is ( values v ...) and whose remaining elements are the same as s.

( seqn-first s)

→

any/c |  | ...

s : sequence?

Returns the first element of s.

( seqn-rest s) → sequence?
s : sequence?

Returns a sequence equivalent to s, except the first element is omitted.

( seqn-length s) → exact-nonnegative-integer?
s : sequence?

Returns the number of elements of s. If s is infinite, this function does not terminate.

( seqn-ref s i)

→

any/c |  | ...

s : sequence?
i : exact-nonnegative-integer?

Returns the ith element of s.

( seqn-tail s i) → sequence?
s : sequence?
i : exact-nonnegative-integer?

Returns a sequence equivalent to s, except the first i elements are omitted.

( seqn-append s ...) → sequence?
s : sequence?

Returns a sequence that contains all elements of each sequence in the order they appear in the original sequences. The new sequence is constructed lazily.

( seqn-map f s) → sequence?
f : procedure?
s : sequence?

Returns a sequence that contains f applied to each element of s. The new sequence is constructed lazily.

( seqn-andmap f s) → boolean?
f : (-> any/c ... boolean?)
s : sequence?

Returns #t if f returns a true result on every element of s. If s is infinite and f never returns a false result, this function does not terminate.

( seqn-ormap f s) → boolean?
f : (-> any/c ... boolean?)
s : sequence?

Returns #t if f returns a true result on some element of s. If s is infinite and f never returns a true result, this function does not terminate.

( seqn-for-each f s) → ( void)
f : (-> any/c ... any)
s : sequence?

Applies f to each element of s. If s is infinite, this function does not terminate.

( seqn-fold f i s) → ( void)
f : (-> any/c any/c ... any/c)
i : any/c
s : sequence?

Folds f over each element of s with i as the initial accumulator. If s is infinite, this function does not terminate.

( seqn-filter f s) → sequence?
f : (-> any/c ... boolean?)
s : sequence?

Returns a sequence whose elements are the elements of s for which f returns a true result. Although the new sequence is constructed lazily, if s has an infinite number of elements where f returns a false result in between two elements where f returns a true result then operations on this sequence will not terminate during that infinite sub-sequence.

( seqn-add-between s e) → sequence?
s : sequence?
e : any/c

Returns a sequence whose elements are the elements of s except in between each is e. The new sequence is constructed lazily.

( seqn-count f s) → exact-nonnegative-integer?
f : procedure?
s : sequence?

Returns the number of elements in s for which f returns a true result. If s is infinite, this function does not terminate.

( in-range end) → sequence?
end : number?
( in-range start end [step]) → sequence?
start : number?
end : number?
step : number? = 1

Returns a sequence whose elements are numbers. The single-argument case ( in-range end) is equivalent to ( in-range 0 end 1). The first number in the sequence is start, and each successive element is generated by adding step to the previous element. The sequence stops before an element that would be greater or equal to end if step is non-negative, or less or equal to end if step is negative.
An in-range application can provide better performance for number iteration when it appears directly in a for clause.

( in-naturals [start]) → sequence?
start : exact-nonnegative-integer? = 0

Returns an infinite sequence of exact integers starting with start, where each element is one more than the preceding element.
An in-naturals application can provide better performance for integer iteration when it appears directly in a for clause.

( in-list lst) → sequence?
lst : list?

Returns a sequence equivalent to lst.

> > > See Pairs and Lists for information on using lists as sequences.

An in-list application can provide better performance for list iteration when it appears directly in a for clause.

( in-mlist mlst) → sequence?
mlst : mlist?

Returns a sequence equivalent to mlst.

> > > See Mutable Pairs and Lists for information on using mutable lists as sequences.

An in-mlist application can provide better performance for mutable list iteration when it appears directly in a for clause.

( in-vector vec [start stop step]) → sequence?
vec : vector?
start : exact-nonnegative-integer? = 0
stop : ( or/c exact-nonnegative-integer? #f) = #f
step : ( and/c exact-integer? ( not/c zero?)) = 1

Returns a sequence equivalent to vec when no optional arguments are supplied.

> > > See Vectors for information on using vectors as sequences.

The optional arguments start, stop, and step are analogous to in-range, except that a #f value for stop is equivalent to ( vector-length vec). That is, the first element in the sequence is ( vector-ref vec start), and each successive element is generated by adding step to index of the previous element. The sequence stops before an index that would be greater or equal to end if step is non-negative, or less or equal to end if step is negative.

If start is less than stop and step is negative, then the exn:fail:contract:mismatch exception is raised. Similarly, if start is more than stop and step is positive, then the exn:fail:contract:mismatch exception is raised. The start and stop values are not checked against the size of vec, so access can fail when an element is demanded from the sequence.

An in-vector application can provide better performance for vector iteration when it appears directly in a for clause.

( in-string str [start stop step]) → sequence?
str : string?
start : exact-nonnegative-integer? = 0
stop : ( or/c exact-nonnegative-integer? #f) = #f
step : ( and/c exact-integer? ( not/c zero?)) = 1

Returns a sequence equivalent to str when no optional arguments are supplied.

> > > See Strings for information on using strings as sequences.

The optional arguments start, stop, and step are as in in-vector.

An in-string application can provide better performance for string iteration when it appears directly in a for clause.

( in-bytes bstr [start stop step]) → sequence?
bstr : bytes?
start : exact-nonnegative-integer? = 0
stop : ( or/c exact-nonnegative-integer? #f) = #f
step : ( and/c exact-integer? ( not/c zero?)) = 1

Returns a sequence equivalent to bstr when no optional arguments are supplied.

> > > See Byte Strings for information on using byte strings as sequences.

The optional arguments start, stop, and step are as in in-vector.

An in-bytes application can provide better performance for byte string iteration when it appears directly in a for clause.

( in-port [r in]) → sequence?
r : ( input-port? . -> . any/c) = read
in : input-port? = ( current-input-port)

Returns a sequence whose elements are produced by calling r on in until it produces eof.

( in-input-port-bytes in) → sequence?
in : input-port?

Returns a sequence equivalent to ( in-port read-byte in).

( in-input-port-chars in) → sequence?
in : input-port?

Returns a sequence whose elements are read as characters form in (equivalent to ( in-port read-char in)).

( in-lines [in mode]) → sequence?
in : input-port? = ( current-input-port)

| mode |  | : |  | ( or/c 'linefeed 'return 'return-linefeed 'any 'any-one)
|  |  | = |  | 'any

Returns a sequence equivalent to ( in-port ( lambda (p) ( read-line p mode)) in). Note that the default mode is 'any, whereas the default mode of read-line is 'linefeed.

( in-bytes-lines [in mode]) → sequence?
in : input-port? = ( current-input-port)

| mode |  | : |  | ( or/c 'linefeed 'return 'return-linefeed 'any 'any-one)
|  |  | = |  | 'any

Returns a sequence equivalent to ( in-port ( lambda (p) ( read-bytes-line p mode)) in). Note that the default mode is 'any, whereas the default mode of read-bytes-line is 'linefeed.

( in-hash hash) → sequence?
hash : hash?

Returns a sequence equivalent to hash.

> > > See Hash Tables for information on using hash tables as sequences.

( in-hash-keys hash) → sequence?
hash : hash?

Returns a sequence whose elements are the keys of hash.

( in-hash-values hash) → sequence?
hash : hash?

Returns a sequence whose elements are the values of hash.

( in-hash-pairs hash) → sequence?
hash : hash?

Returns a sequence whose elements are pairs, each containing a key and its value from hash (as opposed to using hash directly as a sequence to get the key and value as separate values for each element).

( in-directory [dir]) → sequence?
dir : ( or/c #f path-string?) = #f

Return a sequence that produces all of the paths for files, directories, and links with dir. If dir is not #f, then every produced path starts with dir as its prefix. If dir is #f, then paths in and relative to the current directory are produced.

( in-producer producer stop args ...) → sequence?
producer : procedure?
stop : any/c
args : any/c

Returns a sequence that contains values from sequential calls to producer. stop identifies the value that marks the end of the sequence – this value is not included in the sequence. stop can be a predicate or a value that is tested against the results with eq?. Note that you must use a predicate function if the stop value is itself a function, or if the producer returns multiple values.

( in-value v) → sequence?
v : any/c

Returns a sequence that produces a single value: v. This form is mostly useful for let-like bindings in forms such as for*/list.

( in-indexed seq) → sequence?
seq : sequence?

Returns a sequence where each element has two values: the value produced by seq, and a non-negative exact integer starting with 0. The elements of seq must be single-valued.

( in-sequences seq ...) → sequence?
seq : sequence?

Returns a sequence that is made of all input sequences, one after the other. The elements of each seq must all have the same number of values.

( in-cycle seq ...) → sequence?
seq : sequence?

Similar to in-sequences, but the sequences are repeated in an infinite cycle.

( in-parallel seq ...) → sequence?
seq : sequence?

Returns a sequence where each element has as many values as the number of supplied seqs; the values, in order, are the values of each seq. The elements of each seq must be single-valued.

( stop-before seq pred) → sequence?
seq : sequence?
pred : ( any/c . -> . any)

Returns a sequence that contains the elements of seq (which must be single-valued), but only until the last element for which applying pred to the element produces #t, after which the sequence ends.

( stop-after seq pred) → sequence?
seq : sequence?
pred : ( any/c . -> . any)

Returns a sequence that contains the elements of seq (which must be single-valued), but only until the element (inclusive) for which applying pred to the element produces #t, after which the sequence ends.

( make-do-sequence thunk) → sequence?

thunk

:

(-> ( values ( any/c . -> . any)
( any/c . -> . any/c)
any/c
( any/c . -> . any/c)
(() () #:rest list? . ->* . any/c)
(( any/c) () #:rest list? . ->* . any/c)))

Returns a sequence whose elements are generated by the procedures and initial value returned by the thunk. The generator is defined in terms of a position, which is initialized to the third result of the thunk, and the element, which may consist of multiple values.

The thunk results define the generated elements as follows:

- The first result is a pos->element procedure that takes the current position and returns the value(s) for the current element.

- The second result is a next-pos procedure that takes the current position and returns the next position.

- The third result is the initial position.

- The fourth result takes the current position and returns a true result if the sequence includes the value(s) for the current position, and false if the sequence should end instead of including the value(s).

- The fifth result is like the fourth result, but it takes the current element value(s) instead of the current position.

- The sixth result is like the fourth result, but it takes both the current position and the current element values(s) and determines a sequence end after the current element is already included in the sequence.

Each of the procedures listed above is called only once per position. Among the last three procedures, as soon as one of the procedures returns #f, the sequence ends, and none are called again. Typically, one of the functions determines the end condition, and the other two functions always return #t.

prop:sequence : struct-type-property?

Associates a procedure to a structure type that takes an instance of the structure and returns a sequence. If v is an instance of a structure type with this property, then ( sequence? v) produces #t.

Examples:

> ( define-struct train (car next)
#:property prop:sequence ( lambda (t)
( make-do-sequence
( lambda ()
( values train-car
train-next
t
( lambda (t) t)
( lambda (v) #t)
( lambda (t v) #t))))))

> ( for/list ([c (make-train 'engine
(make-train 'boxcar
(make-train 'caboose
#f)))])
c)

'(engine boxcar caboose)

##### 3.14.2`` Sequence Generators

( sequence-generate seq)

→

(-> boolean?) |  | (-> any)

seq : sequence?

Returns two thunks to extract elements from the sequence. The first returns #t if more values are available for the sequence. The second returns the next element (which may be multiple values) from the sequence; if no more elements are available, the exn:fail:contract exception is raised.

##### 3.14.3`` Iterator Generators

( require racket/generator)

( generator () body ...)

Creates a function that returns a value through yield, each time it is invoked. When the generator runs out of values to yield, the last value it computed will be returned for future invocations of the generator. Generators can be safely nested.

Note: The first form must be (). In the future, the () position will hold argument names that are used for the initial generator call.

Examples:

> ( define g ( generator ()
( let loop ([x '(a b c)])
( if ( null? x)
0
( begin
( yield ( car x))
(loop ( cdr x)))))))

> (g)
'a
> (g)
'b
> (g)
'c
> (g)
0
> (g)
0

To use an existing generator as a sequence, you should use in-producer with a stop-value known to the generator.

Examples:
> ( define my-stop-value ( gensym))

> ( define my-generator ( generator ()
( let loop ([x '(a b c)])
( if ( null? x)
my-stop-value
( begin
( yield ( car x))
(loop ( cdr x)))))))

> ( for/list ([i ( in-producer my-generator my-stop-value)])
i)

'(a b c)

( infinite-generator body ...)

Creates a function similar to generator but when the last body is executed the function will re-execute all the bodies in a loop.

Examples:

> ( define welcome
( infinite-generator
( yield 'hello)
( yield 'goodbye)))

> (welcome)
'hello
> (welcome)
'goodbye
> (welcome)
'hello
> (welcome)
'goodbye

( in-generator expr ...) → sequence?
expr : any?

Returns a generator that can be used as a sequence. The in-generator procedure takes care of the case when expr stops producing values, so when the expr completes, the generator will end.

Example:

> ( for/list ([i ( in-generator
( let loop ([x '(a b c)])
( when ( not ( null? x))
( yield ( car x))
(loop ( cdr x)))))])
i)

'(a b c)

( yield expr ...)

Saves the point of execution inside a generator and returns a value. yield can accept any number of arguments and will return them using values.

Values can be passed back to the generator after invoking yield by passing the arguments to the generator instance. Note that a value cannot be passed back to the generator until after the first yield has been invoked.

Examples:
> ( define my-generator ( generator () ( yield 1) ( yield 2 3 4)))
> (my-generator)
1
> (my-generator)
2
3
4

Examples:

> ( define pass-values-generator
( generator ()
( let* ([from-user ( yield 2)]
[from-user-again ( yield ( add1 from-user))])
( yield from-user-again))))

> (pass-values-generator)
2
> (pass-values-generator 5)
6
> (pass-values-generator 12)
12

( generator-state g) → symbol?
g : any?

Returns a symbol that describes the state of the generator.

- 'fresh - The generator has been freshly created and has not been invoked yet. Values cannot be passed to a fresh generator.

- 'suspended - Control within the generator has been suspended due to a call to yield. The generator can be invoked.

- 'running - The generator is currently executing. This state can only be returned if generator-state is invoked inside the generator.

- 'done - The generator has executed its entire body and will not call yield anymore.

Examples:
> ( define my-generator ( generator () ( yield 1) ( yield 2)))
> ( generator-state my-generator)
'fresh
> (my-generator)
1
> ( generator-state my-generator)
'suspended
> (my-generator)
2
> ( generator-state my-generator)
'suspended
> (my-generator)
> ( generator-state my-generator)
'done
> ( define introspective-generator ( generator () (( yield 1))))
> (introspective-generator)
1

> (introspective-generator
( lambda () ( generator-state introspective-generator)))

'running
> ( generator-state introspective-generator)
'done
> (introspective-generator)
'running

( sequence->generator s) → (-> any?)
s : sequence?

Returns a generator that returns elements from the sequence, s, each time the generator is invoked.

( sequence->repeated-generator s) → (-> any?)
s : sequence?

Returns a generator that returns elements from the sequence, s, similar to sequence->generator but looping over the values in the sequence when no more values are left.
top← prev up next →