x-lang

← Index

x/type/gen

Lazy generators: produce-on-demand sequences with the usual functional toolbox.

Lazy generators (unfold-based): build (range/iterate/repeat/from-list/of),

transform lazily (map/filter/take/drop/zip/scan/…), drive eagerly

(->list/fold/sum/find/…). Transformers return a Gen, so chaining never

builds an intermediate list.

Class Gen

A lazy generator: a step function over a state, producing values on demand.

Build with range / range-by / count-from / repeat / iterate / from-list / from-seq / of / flatten, or the make primitive.

Transformers (%map filter take drop take-while drop-while enumerate zip zip-with scan) are lazy – each returns a new Gen.

Consumers (->list ->vector for-each fold reduce count sum product any? all? none? find ref first last min max empty?) drive it.

count-from / repeat / iterate are INFINITE – bound them with take / take-while before any consumer.

step

Field: data carried by a Gen instance.

state

Field: data carried by a Gen instance.

(Gen make step state)

A generator from a raw step function and an initial state – the primitive the rest build on.

Block form: (Gen make (x) body … state) – or (i x) for the 0-based index, then the element.

Parameters:

Returns: Gen — Generator

Examples:

((Gen make (fn (_ n) (if (< n 3) (pair n (+ n 1)) ())) 0) ->list) => (0 1 2)

(Gen range start stop)

Integers from start up to (not including) stop.

Parameters:

Returns: Gen — Generator

Examples:

((Gen range 0 4) ->list) => (0 1 2 3)

(Gen range-by start stop by)

Integers from start toward stop, stepping by by.

Parameters:

Returns: Gen — Generator

Examples:

((Gen range-by 0 10 3) ->list) => (0 3 6 9)

(Gen count-from start)

INFINITE: start, start+1, start+2, … Bound with take / take-while.

Parameters:

Returns: Gen — Infinite generator

Examples:

(((Gen count-from 1) take 3) ->list) => (1 2 3)

(Gen repeat x)

INFINITE: x, x, x, … Bound with take.

Parameters:

Returns: Gen — Infinite generator

Examples:

(((Gen repeat 7) take 3) ->list) => (7 7 7)

(Gen iterate f x)

INFINITE: x, (f x), (f (f x)), … Bound with take / take-while.

Block form: (Gen iterate (x) body … x) – or (i x) for the 0-based index, then the element.

Parameters:

Returns: Gen — Infinite generator

Examples:

(((Gen iterate (fn (_ n) (* n 2)) 1) take 4) ->list) => (1 2 4 8)

(Gen from-seq v)

A generator over any iterable value, driven functionally by the C iterator steps: the state is an Iter, stepped without mutation.

Parameters:

Returns: Gen — Generator

Examples:

((Gen from-seq (Vector of 1 2 3)) ->list) => (1 2 3)

(Gen from-list lst)

A generator over a list’s elements.

Parameters:

Returns: Gen — Generator

Examples:

((Gen from-list (list 1 2 3)) ->list) => (1 2 3)

(Gen of . args)

A generator over the given values.

Parameters:

Returns: Gen — Generator

Examples:

((Gen of 1 2 3) ->list) => (1 2 3)

(Gen flatten v)

A generator over v walked depth first: a list or a Gen inside it is walked in its place, and every other value is yielded as it is (lazy).

Lists and Gens are walked; strings, vectors and other objects are values, as in List flatten. A v that is neither is yielded once.

A Gen is not stepped until the walk reaches it, so one that is INFINITE makes the walk infinite: bound it with take / take-while.

Parameters:

Returns: Gen — Generator

Examples:

((Gen flatten (list 1 (Gen range 2 4) (list 4 (list 5)))) ->list) => (1 2 3 4 5)

(%next)

Instance method: called on a Gen instance.

(map f)

A generator that applies f to each value (lazy).

Instance method: called on a Gen instance.

Block form: (map (x) body …) – or (i x) for the 0-based index, then the element.

Parameters:

Returns: Gen — Generator

Examples:

(((Gen range 0 4) map (fn (_ x) (* x x))) ->list) => (0 1 4 9)

(filter p)

A generator of the values for which p holds (lazy).

Instance method: called on a Gen instance.

Block form: (filter (x) body …) – or (i x) for the 0-based index, then the element.

Parameters:

Returns: Gen — Generator

Examples:

(((Gen range 0 6) filter (fn (_ x) (< x 3))) ->list) => (0 1 2)

(take n)

A generator of at most the first n values (lazy).

Instance method: called on a Gen instance.

Parameters:

Returns: Gen — Generator

Examples:

(((Gen count-from 0) take 3) ->list) => (0 1 2)

(drop n)

A generator that skips the first n values (lazy).

Instance method: called on a Gen instance.

Parameters:

Returns: Gen — Generator

Examples:

(((Gen range 0 5) drop 2) ->list) => (2 3 4)

(take-while p)

Values up to (not including) the first for which p fails (lazy).

Instance method: called on a Gen instance.

Block form: (take-while (x) body …) – or (i x) for the 0-based index, then the element.

Parameters:

Returns: Gen — Generator

Examples:

(((Gen count-from 1) take-while (fn (_ x) (< x 4))) ->list) => (1 2 3)

(drop-while p)

Skip the leading run for which p holds, then yield the rest (lazy).

Instance method: called on a Gen instance.

Block form: (drop-while (x) body …) – or (i x) for the 0-based index, then the element.

Parameters:

Returns: Gen — Generator

Examples:

(((Gen range 0 6) drop-while (fn (_ x) (< x 3))) ->list) => (3 4 5)

(enumerate)

Pair each value with its 0-based index: (index . value) (lazy).

Instance method: called on a Gen instance.

Returns: Gen — Generator

Examples:

(((Gen of 10 20) enumerate) ->list) => ((0 . 10) (1 . 20))

(zip-with f other)

Combine corresponding values of two generators with f; stops at the shorter (lazy).

Instance method: called on a Gen instance.

Block form: (zip-with (a b) body … other).

Parameters:

Returns: Gen — Generator

Examples:

(((Gen range 0 3) zip-with (fn (_ a b) (+ a b)) (Gen range 10 13)) ->list) => (10 12 14)

(zip other)

Pair corresponding values of two generators; stops at the shorter (lazy).

Instance method: called on a Gen instance.

Parameters:

Returns: Gen — Generator

Examples:

(((Gen range 0 2) zip (Gen of 10 20)) ->list) => ((0 . 10) (1 . 20))

(scan f init)

Running left-fold: emits init’s successive updates (lazy).

Instance method: called on a Gen instance.

Block form: (scan (acc x) body … init) – or (acc i x) with the 0-based index ahead of the element.

Parameters:

Returns: Gen — Generator

Examples:

(((Gen range 1 5) scan (fn (_ a x) (+ a x)) 0) ->list) => (1 3 6 10)

(flatten)

This generator walked depth first: a list or a Gen among its values is walked in its place (lazy). See the static flatten.

Instance method: called on a Gen instance.

Lists and Gens are walked; strings, vectors and other objects are values, as in List flatten. A v that is neither is yielded once.

A Gen is not stepped until the walk reaches it, so one that is INFINITE makes the walk infinite: bound it with take / take-while.

Returns: Gen — Generator

Examples:

(((Gen of 1 (list 2 3) (Gen range 4 6)) flatten) ->list) => (1 2 3 4 5)

(fold f acc)

Left-fold f over every value.

Instance method: called on a Gen instance.

Block form: (fold (acc x) body … acc) – or (acc i x) with the 0-based index ahead of the element.

Parameters:

Returns: ANY — Final accumulator

Examples:

((Gen range 1 5) fold (fn (_ a x) (+ a x)) 0) => 10

(for-each f)

Apply f to each value, in order.

Instance method: called on a Gen instance.

Block form: (for-each (x) body …) – or (i x) for the 0-based index, then the element.

Parameters:

Returns: Gen — self

(->list)

Materialise the generator as a list.

Instance method: called on a Gen instance.

Returns: LIST — All the values

Examples:

((Gen range 0 3) ->list) => (0 1 2)

(->vector)

Materialise the generator as a vector.

Instance method: called on a Gen instance.

Returns: VECTOR — All the values

Examples:

((Gen range 0 3) ->vector) => #(0 1 2)

(count)

Count the values by consuming the generator (not for infinite ones). Deliberately count, not length: a lazy stream has no length property – counting it is an action.

Instance method: called on a Gen instance.

Returns: INTEGER — Count

Examples:

((Gen range 0 5) count) => 5

(sum)

Sum of the values.

Instance method: called on a Gen instance.

Returns: NUMBER — Sum

Examples:

((Gen range 1 5) sum) => 10

(product)

Product of the values.

Instance method: called on a Gen instance.

Returns: NUMBER — Product

Examples:

((Gen range 1 5) product) => 24

(empty?)

Test whether the generator yields no values. Peeks one step – a Gen is persistent, so nothing is consumed.

Instance method: called on a Gen instance.

Returns: BOOL — #t when empty

Examples:

((Gen of) empty?) => #t
((Gen range 0 3) empty?) => #f

(reduce f)

Fold using the first value as the seed; errors on an empty generator (empty? is the presence door).

Instance method: called on a Gen instance.

Block form: (reduce (a b) body …).

Parameters:

Returns: ANY — Reduced value

Examples:

((Gen of 3 1 2) reduce (fn (_ a x) (* a x))) => 6

(any? p)

t if p holds for any value; short-circuits.

Instance method: called on a Gen instance.

Block form: (any? (x) body …) – or (i x) for the 0-based index, then the element.

Parameters:

Returns: BOOL — t/f

Examples:

((Gen range 0 5) any? (fn (_ x) (> x 3))) => #t

(all? p)

t if p holds for every value; short-circuits.

Instance method: called on a Gen instance.

Block form: (all? (x) body …) – or (i x) for the 0-based index, then the element.

Parameters:

Returns: BOOL — t/f

Examples:

((Gen range 0 5) all? (fn (_ x) (< x 5))) => #t

(none? p)

t if p holds for no value.

Instance method: called on a Gen instance.

Block form: (none? (x) body …) – or (i x) for the 0-based index, then the element.

Parameters:

Returns: BOOL — t/f

Examples:

((Gen range 0 5) none? (fn (_ x) (> x 9))) => #t

(find p)

The first value satisfying p, or ().

Instance method: called on a Gen instance.

Block form: (find (x) body …) – or (i x) for the 0-based index, then the element.

Parameters:

Returns: ANY — Value or nil

Examples:

((Gen count-from 1) find (fn (_ x) (> (* x x) 20))) => 5

(ref n)

The n-th value (0-based); errors when n is negative (a lazy stream has no end to count from) or past the last value.

Instance method: called on a Gen instance.

Parameters:

Returns: ANY — Value at n

Examples:

((Gen range 10 20) ref 3) => 13

(first)

The first value; errors on an empty generator (empty? is the presence door).

Instance method: called on a Gen instance.

Returns: ANY — First value

Examples:

((Gen range 5 9) first) => 5

(last)

The last value; errors on an empty generator (drives the whole generator).

Instance method: called on a Gen instance.

Returns: ANY — Last value

Examples:

((Gen range 5 9) last) => 8

(min)

The least value; errors on an empty generator (drives the whole generator).

Instance method: called on a Gen instance.

Returns: ANY — Least value

Examples:

((Gen of 3 1 2) min) => 1

(max)

The greatest value; errors on an empty generator (drives the whole generator).

Instance method: called on a Gen instance.

Returns: ANY — Greatest value

Examples:

((Gen of 3 1 2) max) => 3