;;; http://srfi.schemers.org/srfi-40/srfi-40.txt ;;; ...two kinds of streams: odd streams as in SICP et al, and even ;;; streams, as in haskell; the names odd and even refer to the parity ;;; of the number of constructors (delay, cons, nil) used to represent ;;; the stream ;;; FIGURE 1 -- ODD (define nil1 '()) (define (nil1? strm) (null? strm)) (define-syntax cons1 (syntax-rules () ((cons1 obj strm) (cons obj (delay strm))))) (define (car1 strm) (car strm)) (define (cdr1 strm) (force (cdr strm))) (define (map1 func strm) (if (nil1? strm) nil1 (cons1 (func (car1 strm)) (map1 func (cdr1 strm))))) (define (countdown1 n) (cons1 n (countdown1 (- n 1)))) (define (cutoff1 n strm) (cond ((zero? n) '()) ((nil1? strm) '()) (else (cons (car1 strm) (cutoff1 (- n 1) (cdr1 strm)))))) ;;; FIGURE 2 -- EVEN (define nil2 (delay '())) (define (nil2? strm) (null? (force strm))) (define-syntax cons2 (syntax-rules () ((cons2 obj strm) (delay (cons obj strm))))) (define (car2 strm) (car (force strm))) (define (cdr2 strm) (cdr (force strm))) (define (map2 func strm) (delay (force (if (nil2? strm) nil2 (cons2 (func (car2 strm)) (map2 func (cdr2 strm))))))) (define (countdown2 n) (delay (force (cons2 n (countdown2 (- n 1)))))) (define (cutoff2 n strm) (cond ((zero? n) '()) ((nil2? strm) '()) (else (cons (car2 strm) (cutoff2 (- n 1) (cdr2 strm)))))) ;; sample use (define (test-odd) ; error: divide by zero (define (12div n) (/ 12 n)) (cutoff1 4 (map1 12div (countdown1 4)))) (define (test-even) ; (3 4 6 12) (define (12div n) (/ 12 n)) (cutoff2 4 (map2 12div (countdown2 4)))) ;;; FIGURE 3 -- EASY ;;; hiding the (delay (force ...)) construct with syntax (define nil3 (delay '())) (define (nil3? strm) (null? (force strm))) (define-syntax cons3 (syntax-rules () ((cons3 obj strm) (delay (cons obj strm))))) (define (car3 strm) (car (force strm))) (define (cdr3 strm) (cdr (force strm))) (define-syntax stream-define (syntax-rules () ((stream-define (name args ...) body0 body1 ...) (define (name args ...) (delay (force (begin body0 body1 ...))))))) (stream-define (map3 func strm) (if (nil3? strm) nil3 (cons3 (func (car3 strm)) (map3 func (cdr3 strm))))) (stream-define (countdown3 n) (cons3 n (countdown3 (- n 1)))) (define (cutoff3 n strm) (cond ((zero? n) '()) ((nil3? strm) '()) (else (cons (car3 strm) (cutoff3 (- n 1) (cdr3 strm))))))