Lazy Evaluation and Streams
Racket: racket/stream and #lang lazy. Common Lisp: libraries like series and lazy-seq implementations. Streams model infinite data, signal processing, and separation of generation from consumption.
;; SICP streams: delay the tail
(define-syntax cons-stream
(syntax-rules ()
((_ a b) (cons a (delay b)))))
(define (stream-car s) (car s))
(define (stream-cdr s) (force (cdr s)))
(define the-empty-stream '())
(define stream-null? null?)
(define (integers-from n) (cons-stream n (integers-from (+ n 1))))
(define naturals (integers-from 0))
(define (stream-take s n)
(if (= n 0) '() (cons (stream-car s) (stream-take (stream-cdr s) (- n 1)))))
(define (stream-filter pred s)
(if (pred (stream-car s))
(cons-stream (stream-car s) (stream-filter pred (stream-cdr s)))
(stream-filter pred (stream-cdr s))))
(define (stream-map f s) (cons-stream (f (stream-car s)) (stream-map f (stream-cdr s))))
(stream-take (stream-filter even? naturals) 5) ; (0 2 4 6 8)
;; Sieve of Eratosthenes as a stream
(define (sieve s)
(cons-stream (stream-car s)
(sieve (stream-filter (lambda (x) (not (= 0 (remainder x (stream-car s)))))
(stream-cdr s)))))
(stream-take (sieve (integers-from 2)) 10) ; (2 3 5 7 11 13 17 19 23 29);; Clojure: lazy sequences are the default for map/filter/range/iterate
(def fibs (lazy-cat [0 1] (map + fibs (rest fibs))))
(take 10 fibs) ; (0 1 1 2 3 5 8 13 21 34)
(take 5 (filter even? (range))) ; (0 2 4 6 8)