Chapter 3, Modularity, Objects, and State
Exercise 3.81
This is an interesting example to see the difference between imperative approach and stream based approach.
I created an auxillary procedure for to help in creating streams from lists.
Let’s first check the output:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1 ]=> (define
requests
(list->stream
'((reset 512)
generate
generate
(reset 512)
generate
generate
generate
reset
generate
generate
reset
generate
generate
generate)))
;Value: requests
1 ]=> (define random-stream-gen (make-rand-gen 729 1000))
;Value: random-stream-gen
1 ]=> (define random-stream (random-stream-gen requests))
;Value: random-stream
1 ]=> (get-n-items-of-stream random-stream 14)
;Value 55: (871 282 201 871 282 201 852 164 779 614 164 779 614 . 829)
Now, I think it is easier to understand the code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
(define (make-rand-gen default-seed upper-bound)
;Using foot-note 6 from chapter-3 to implement rand-update
(define (rand-update x)
(remainder (+ (* 29 x) 23) upper-bound))
(define (gen request old-val)
(cond ((and (pair? request) (eq? 'reset (car request))) (rand-update (cadr request)))
((eq? 'reset request) (rand-update default-seed))
((eq? 'generate request) (rand-update old-val))
(else 'invalid)
))
(define (make-rand-stream requests)
(define s
(cons-stream
(gen (stream-car requests) default-seed)
(stream-map gen
(stream-cdr requests)
s)))
s)
make-rand-stream)
(define (list->stream l)
(cons-stream (car l) (list->stream (cdr l))))