150 likes | 435 Views
(defmacro (delay x) (list 'lambda () x)) (define (force (promise <function>)) (promise)) ==> (define p (delay (print "hello"))) ==> (force p) hello. (defclass <stream> ()) (defclass <null-stream> (<stream>)) (defclass <cons-stream> (<stream>) (head-stream :accessor head-stream
E N D
(defmacro (delay x) (list 'lambda () x)) (define (force (promise <function>)) (promise)) ==> (define p (delay (print "hello"))) ==> (force p) hello
(defclass <stream> ()) (defclass <null-stream> (<stream>)) (defclass <cons-stream> (<stream>) (head-stream :accessor head-stream :initarg :head) (tail-stream :type <function> :accessor tail-stream :initarg :tail)) (defmacro (cons-stream o s) (list 'make <cons-stream> :head o :tail (list 'delay s))) (genericify (head o)) (genericify (tail o)) (defmethod (head (s <stream>)) (head-stream s)) (defmethod (tail (s <stream>)) (force (tail-stream s)))
(defmethod (filter (test <function>) (stream <stream>)) (cond ((null-stream? stream) null-stream) ((test (head stream)) (cons-stream (head stream) (filter test (tail stream)))) (else (filter test (tail stream))))) (defmethod (map (f <function>) (stream <stream>)) (if (null-stream? stream) null-stream (cons-stream (f (head stream)) (map f (tail stream))))) (defmethod (accumulate (combiner <function>) (init <object>) (stream <stream>)) (if (null-stream? stream) init (combiner (head stream) (accumulate combiner init (tail stream)))))
;; (1 1 1 1 1 1 1 1 1 1 ... (define ones (cons-stream 1 ones)) ;; (0 1 2 3 4 5 6 7 8 9 10 ... (define (integers-from (n <integer>)) (cons-stream n (integers-from (add1 n)))) (define naturals (integers-from 0)) ;; (low low+1 ... high) (define (interval low high) (if (> low high) null-stream (cons-stream low (interval (add1 low) high))))
;; print out first n elements of a stream (define (initial (n <integer>) (s <stream>)) (cond ((< n 1) (echo)) ((null-stream? s) (print "[end of stream]")) (else (printf "~a " (head s)) (initial (sub1 n) (tail s))))) ==> (initial 20 ones) 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ==> (initial 20 naturals) 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ==> (initial 20 (interval 1 10)) 1 2 3 4 5 6 7 8 9 10 [end of stream]
(define (divisible? (x <integer>) (n <integer>)) (zero? (modulo x n))) (define multiples-of-3 (filter (lambda (x) (divisible? x 3)) naturals)) ==> (initial 20 multiples-of-3) 0 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57
;; sieve of Eratosthenes (define (sieve (stream <stream>)) (cons-stream (head stream) ;head is prime (sieve ;recursively sieve tail after (filter ;removing all multiples of head (lambda (x) (not (divisible? x (head stream)))) (tail stream))))) ;; stream of primes (define primes (sieve (integers-from 2))) ==> (initial 20 primes) 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71
(define (add-streams (a <stream>) (b <stream>)) (cond ((null-stream? a) b) ((null-stream? b) a) (else (cons-stream (+ (head a) (head b)) (add-streams (tail a) (tail b)))))) ;; alternative definition of (0 1 2 3 4 5 ... (define naturals-1 (cons-stream 0 (add-streams ones naturals))) ==> (initial 20 naturals-1) 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
;; fibonacci numbers (0 1 1 2 3 5 8 13 ... (define slow-fibs (cons-stream 0 (cons-stream 1 (add-streams slow-fibs (tail slow-fibs))))) ==> (initial 15 slow-fibs) 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
;; a more efficient version of fibonacci numbers (define (fibs-from (a <integer>) (b <integer>)) (cons-stream a (fibs-from b (+ a b)))) (define fast-fibs (fibs-from 0 1)) ==> (initial 20 fast-fibs) 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181
Merge two streams into one Example: joint bank account Dexter stream: 1/1/00 23:59 deposit $500 1/15/00 23:59 deposit $500 2/1/00 23:59 deposit $500 2/15/00 23:59 deposit $500 ... Fran stream: 1/3/00 10:36 withdraw $200 1/7/00 14:15 withdraw $150 1/10/00 15:44 withdraw $500 1/19/00 9:05 withdraw $825 ...
;; merge two ordered streams (define (merge (s1 <stream>) (s2 <stream>)) (cond ((null-stream? s1) s2) ((null-stream? s2) s1) ((< (head s1) (head s2)) (cons-stream (head s1) (merge (tail s1) s2))) (else (cons-stream (head s2) (merge s1 (tail s2)))))) ==> (initial 20 (merge naturals naturals)) 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9
A Divergent Computation (define lose (filter odd? (filter even? naturals)))
(define random-bits (cons-stream (random 2) random-bits)) ==> (initial 20 random-bits) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ==> (initial 20 random-bits) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ==> (initial 20 random-bits) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 (define random-bits (cons-stream (random 2) random-bits)) ==> (initial 20 random-bits) 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ==> (initial 20 random-bits) 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ==> (initial 20 random-bits) 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
;; random bit stream (define random-bits (letrec ((promised-random-bits (cons-stream (delay (random 2)) promised-random-bits))) (map force promised-random-bits))) ==> (initial 20 random-bits) 1 0 0 1 0 1 0 0 0 0 1 1 1 0 0 0 0 1 0 1 ==> (initial 20 random-bits) 1 0 1 0 0 1 1 0 1 1 1 0 1 1 0 1 0 0 0 1 ==> (initial 20 random-bits) 1 1 0 0 1 1 0 1 0 0 0 1 1 1 1 1 0 0 1 0