stream-values
(require stream-values) | package: stream-values |
This library allows manipulation of multiple values in streams. The for/stream/values form, in particular, could be used to construct a relatively efficient sequence of multiple values in the traditional (3m) variant of Racket (as generators are highly inefficient in this variant).
syntax
(stream-cons/values first-expr rest-expr)
syntax
(stream/values expr ...)
syntax
(stream*/values expr ...)
syntax
(for/stream/values (for-clause ...) body-or-break ... body)
syntax
(for*/stream/values (for-clause ...) body-or-break ... body)
> (define s (stream-cons/values (values 1 2) empty-stream)) > (stream-first s)
1
2
> (define t (stream/values (values 1 2) (values 3 4)))
> (for/list ([(left right) (in-stream t)]) (list left right)) '((1 2) (3 4))
> (define u (for/stream/values ([i (in-naturals)]) (values i (add1 i))))
> (for/list ([(left right) u] [_ 5]) (list left right)) '((0 1) (1 2) (2 3) (3 4) (4 5))
procedure
(unsafe-in-stream s) → sequence?
s : stream?
This procedure is useful when a stream is used in the iteration only once and then discarded, since memoization does not matter and the iteration could be significantly faster. On the other hand, if the stream will be used again in the future, the lack of memoization could result in a performance loss or even a surprisingly incorrect result.
; Performance of in-stream vs unsafe-in-stream > (define s (for/stream/values ([i (in-range 100000)]) (values i (add1 i)))) > (time (for ([(a b) (in-stream s)]) (void))) cpu time: 88 real time: 88 gc time: 16
> (define t (for/stream/values ([i (in-range 100000)]) (values i (add1 i)))) > (time (for ([(a b) (unsafe-in-stream t)]) (void))) cpu time: 14 real time: 14 gc time: 0
; Lack of memoization > (define xs (for/stream/values ([i (in-range 5)]) (displayln i))) > (for ([_ (in-stream xs)]) (void))
0
1
2
3
4
; This iteration should not display any element because the stream is memoized. > (for ([_ (in-stream xs)]) (void)) > (define ys (for/stream/values ([i (in-range 5)]) (displayln i))) > (for ([_ (unsafe-in-stream ys)]) (void))
0
1
2
3
4
; Due to the lack of memoization, this iteration displays elements again. > (for ([_ (unsafe-in-stream ys)]) (void))
0
1
2
3
4
; Fully memoization stream is utilized > (define zs (for/stream/values ([i (in-range 5)]) (displayln i))) > (for ([_ (in-stream zs)]) (void))
0
1
2
3
4
; This iteration should not display any element because the stream is fully memoized. > (for ([_ (unsafe-in-stream zs)]) (void))
; Performance of in-stream vs unsafe-in-stream on fully memoized stream. > (define w (for/stream/values ([i (in-range 100000)]) (values i (add1 i)))) ; Fully memoize w first. > (for ([(a b) (in-stream w)]) (void)) > (time (for ([(a b) (in-stream w)]) (void))) cpu time: 64 real time: 64 gc time: 0
> (time (for ([(a b) (unsafe-in-stream w)]) (void))) cpu time: 113 real time: 113 gc time: 0