1 665c255d 2023-08-04 jrmu (define (memo-proc proc)
2 665c255d 2023-08-04 jrmu (let ((already-run? false) (result false))
4 665c255d 2023-08-04 jrmu (if already-run?
6 665c255d 2023-08-04 jrmu (begin (set! already-run? true)
7 665c255d 2023-08-04 jrmu (set! result (proc))
10 665c255d 2023-08-04 jrmu (define-syntax mydelay
11 665c255d 2023-08-04 jrmu (rsc-macro-transformer
13 665c255d 2023-08-04 jrmu (lambda (exp)
14 665c255d 2023-08-04 jrmu `(memo-proc (lambda () ,exp)))))
15 665c255d 2023-08-04 jrmu (lambda (e r)
16 665c255d 2023-08-04 jrmu (apply xfmr (cdr e))))))
18 665c255d 2023-08-04 jrmu (define (myforce delayed-object)
19 665c255d 2023-08-04 jrmu (delayed-object))
21 665c255d 2023-08-04 jrmu (define-syntax cons-stream
22 665c255d 2023-08-04 jrmu (rsc-macro-transformer
23 665c255d 2023-08-04 jrmu (let ((xfmr (lambda (x y) `(cons ,x (mydelay ,y)))))
24 665c255d 2023-08-04 jrmu (lambda (e r)
25 665c255d 2023-08-04 jrmu (apply xfmr (cdr e))))))
27 665c255d 2023-08-04 jrmu (define (stream-car s)
29 665c255d 2023-08-04 jrmu (define (stream-cdr s)
30 665c255d 2023-08-04 jrmu (myforce (cdr s)))
31 665c255d 2023-08-04 jrmu (define stream-null? null?)
32 665c255d 2023-08-04 jrmu (define the-empty-stream '())
34 665c255d 2023-08-04 jrmu (define (integers-starting-from n)
35 665c255d 2023-08-04 jrmu (cons-stream n (integers-starting-from (+ n 1))))
37 665c255d 2023-08-04 jrmu (define (stream-ref s n)
39 665c255d 2023-08-04 jrmu (stream-car s)
40 665c255d 2023-08-04 jrmu (stream-ref (stream-cdr s) (- n 1))))
41 665c255d 2023-08-04 jrmu (define (stream-map proc s)
42 665c255d 2023-08-04 jrmu (if (stream-null? s)
43 665c255d 2023-08-04 jrmu the-empty-stream
44 665c255d 2023-08-04 jrmu (cons-stream (proc (stream-car s))
45 665c255d 2023-08-04 jrmu (stream-map proc (stream-cdr s)))))
46 665c255d 2023-08-04 jrmu (define (stream-for-each proc s)
47 665c255d 2023-08-04 jrmu (if (stream-null? s)
49 665c255d 2023-08-04 jrmu (begin (proc (stream-car s))
50 665c255d 2023-08-04 jrmu (stream-for-each proc (stream-cdr s)))))
52 665c255d 2023-08-04 jrmu (define (stream-enumerate-interval low high)
53 665c255d 2023-08-04 jrmu (if (> low high)
54 665c255d 2023-08-04 jrmu the-empty-stream
55 665c255d 2023-08-04 jrmu (cons-stream
57 665c255d 2023-08-04 jrmu (stream-enumerate-interval (+ low 1) high))))
58 665c255d 2023-08-04 jrmu (define (stream-filter pred s)
59 665c255d 2023-08-04 jrmu (if (stream-null? s)
60 665c255d 2023-08-04 jrmu the-empty-stream
61 665c255d 2023-08-04 jrmu (let ((scar (stream-car s)))
62 665c255d 2023-08-04 jrmu (if (pred scar)
63 665c255d 2023-08-04 jrmu (cons-stream scar (stream-filter pred (stream-cdr s)))
64 665c255d 2023-08-04 jrmu (stream-filter pred (stream-cdr s))))))
66 665c255d 2023-08-04 jrmu (define (display-stream s)
67 665c255d 2023-08-04 jrmu (stream-for-each display-line s))
68 665c255d 2023-08-04 jrmu (define (display-line x)
70 665c255d 2023-08-04 jrmu (display x))
72 665c255d 2023-08-04 jrmu (define (test-case actual expected)
74 665c255d 2023-08-04 jrmu (display "Actual: ")
75 665c255d 2023-08-04 jrmu (display actual)
77 665c255d 2023-08-04 jrmu (display "Expected: ")
78 665c255d 2023-08-04 jrmu (display expected)
81 665c255d 2023-08-04 jrmu ;; Exercise 3.52. Consider the sequence of expressions
83 665c255d 2023-08-04 jrmu (define sum 0)
84 665c255d 2023-08-04 jrmu (define (accum x)
85 665c255d 2023-08-04 jrmu (set! sum (+ x sum))
87 665c255d 2023-08-04 jrmu (define seq (stream-map accum (stream-enumerate-interval 1 20)))
88 665c255d 2023-08-04 jrmu (test-case sum 1)
89 665c255d 2023-08-04 jrmu (define y (stream-filter even? seq))
90 665c255d 2023-08-04 jrmu (test-case sum 6)
91 665c255d 2023-08-04 jrmu (define z (stream-filter (lambda (x) (= (remainder x 5) 0))
93 665c255d 2023-08-04 jrmu (test-case sum 10)
94 665c255d 2023-08-04 jrmu (stream-ref y 7)
95 665c255d 2023-08-04 jrmu ;; 1 3 6 10 15 21 28 36 45 55 66 78 91 105 120 136
96 665c255d 2023-08-04 jrmu (test-case sum 136)
97 665c255d 2023-08-04 jrmu (display-stream z)
98 665c255d 2023-08-04 jrmu ;; 1 3 6 10 15 21 28 36 45 55 66 78 91 105 120 136 153 171 190 210
100 665c255d 2023-08-04 jrmu (display '(10 15 45 55 105 120 190 210))
102 665c255d 2023-08-04 jrmu ;; What is the value of sum after each of the above expressions is evaluated? What is the printed response to evaluating the stream-ref and display-stream expressions? Would these responses differ if we had implemented (delay <exp>) simply as (lambda () <exp>) without using the optimization provided by memo-proc ? Explain.
104 665c255d 2023-08-04 jrmu (define (memo-proc proc)
105 665c255d 2023-08-04 jrmu proc) ;; get rid of the optimization
106 665c255d 2023-08-04 jrmu (define sum 0)
107 665c255d 2023-08-04 jrmu (define (accum x)
108 665c255d 2023-08-04 jrmu (set! sum (+ x sum))
110 665c255d 2023-08-04 jrmu (define seq (stream-map accum (stream-enumerate-interval 1 20)))
111 665c255d 2023-08-04 jrmu (test-case sum 1)
112 665c255d 2023-08-04 jrmu (define y (stream-filter even? seq))
113 665c255d 2023-08-04 jrmu (test-case sum 6)
114 665c255d 2023-08-04 jrmu (define z (stream-filter (lambda (x) (= (remainder x 5) 0))
116 665c255d 2023-08-04 jrmu ;; 1 8 11 15
117 665c255d 2023-08-04 jrmu (test-case sum 15)
118 665c255d 2023-08-04 jrmu (stream-ref y 7)
120 665c255d 2023-08-04 jrmu ;; *6 19 *24 *30 37 45 *54 *64 75 87 *100 *114 129 145 *162
121 665c255d 2023-08-04 jrmu (test-case sum 162)
122 665c255d 2023-08-04 jrmu (display-stream z)
123 665c255d 2023-08-04 jrmu ;; *15 167 173 *180 188 197 207 218 *230 243 257 272 288 *305 323 342 362
125 665c255d 2023-08-04 jrmu (display '(15 180 230 305))