We use SG (Stream Generator) consistently to characterize a Scheme value that presents some particular stream of values z0, z1, ... zn, according to the following logic: ((Z)) => z0, (let ((r (Z))) (r) (r)) => z1 etc. Z is immutable while (Z) yields a procedure which yields the successive elements of the stream on successive calls and yields #f after yielding zn. Successive calls to Z always yield a new generator just like the last.
Routines SG->lst & lst->SG convert between Scheme lists and streams. (fs sg fil) takes an SG and a filter (element predicate) and returns another SG that produces the elements that pass the filter. (Cart g h) takes two such SG’s and returns a third for the Cartesian product, which produces pairs.
; map each element of a stream by fun for another stream. (define (sm sg fun)(lambda () (let ((s (sg))) (lambda () (let ((ne (s))) (and ne (fun ne))))))) ; Stream of integers thru k-1 (define (si k) (lambda () (let ((n 0)) (lambda () (and (< n k) (let ((i n)) (set! n (+ n 1)) i)))))) (define (SG->lst sg) (reverse (let ((g (sg))) (let w ((e (g))(lst '())) (if e (w (g) (cons e lst)) lst))))) (define (lst->SG l) (lambda () (let ((c l)) (lambda () (and (pair? c) (let ((v (car c))) (begin (set! c (cdr c)) v))))))) ; filtered substream: (define (fs sg fil) (lambda () (let ((sc (sg))) (lambda () (let scan () (let ((ne (sc))) (and ne (if (fil ne) ne (scan))))))))) ; Cartesian product of two streams, streamed. (define (Cart g h) (lambda () (let* ((G (g))(H (h))(gs (G))) (lambda () (let ((n (H))) (if (not n) (begin (set! H (h)) (set! gs (G)) (set! n (H)))) (and gs (cons gs n))))))) ; String to Stream converter. (define (str->str st) (let ((l (string-length st))) (lambda () (let ((n 0)) (lambda () (and (< n l) (let ((ch (string-ref st n))) (set! n (+ n 1)) ch)))))))Demos:
(SG->lst (fs (si 25) odd?)) ; => (1 3 5 7 9 11 13 15 17 19 21 23) (SG->lst (Cart (si 2)(si 3))) ; => ((0 . 0) (0 . 1) (0 . 2) (1 . 0) (1 . 1) (1 . 2)) (SG->lst (sm (si 6) -)) ; => (0 -1 -2 -3 -4 -5) (SG->lst (str->str "flub")) ; => (#\f #\l #\u #\b)