List builder
The :std/misc/list-builder
library provides
common bindings for building lists.
To use the bindings from this module:
(import :std/misc/list-builder)
with-list-builder
(with-list-builder (put! [peek]) body ...) -> list
put! := function identifier that modifies internal list
peek := optional function identifier that retrieves internal list
A more efficient Syntax sugar for the call-with-list-builder
procedure,
so put! and peek can be used without wrapping them in a lambda first.
with-list-builder
returns the internal list at the end.
Examples:
> (import :std/iter)
> (with-list-builder (put!)
(for (n (in-iota 100 1))
(let ((mod3 (zero? (modulo n 3)))
(mod5 (zero? (modulo n 5))))
(put! (cond ((and mod3 mod5) "fizzbuzz")
(mod3 "fizz")
(mod5 "buzz")
(else n))))))
(1 2 "fizz" 4 "buzz" "fizz" ... 97 98 "fizz" "buzz")
call-with-list-builder
(call-with-list-builder proc) -> list
proc := procedure that takes two proc identifiers as input
Takes a procedure or lambda proc which itself takes two procedures that can have any name but are called put! and peek here:
- put! will append its input element onto the list being built.
- peek retrieves the elements collected so far (initially
[]
).
Note that the list is built my mutation, so that the result of peek
may be mutated by subsequent calls to poke
, and you must copy it
with copy-list
if you want not to be affected by these mutations.
Finally, call-with-list-builder
returns the constructed list.
Examples:
> (import :std/iter)
> (call-with-list-builder
(lambda (put! peek)
(for (x (in-range 5 10))
(displayln (peek))
(put! (random-integer (1+ x))))))
() ; first call to peek, no prior put!
(5)
(5 6)
(5 6 2)
(5 6 2 8) ; fifth explicit peek call
(5 6 2 8 6) ; final result printed by the REPL after the call returns