]> git.rkrishnan.org Git - sicp.git/blob - src/sicp/ex3_51.rkt
Solution to 4.44. A bit too verbose. Can be improved by better
[sicp.git] / src / sicp / ex3_51.rkt
1 #lang planet neil/sicp 
2
3 (define (stream-car s) (car s))
4 (define (stream-cdr s) (force (cdr s)))
5
6 (define (stream-ref s n)
7   (if (= n 0)
8       (stream-car s)
9       (stream-ref (stream-cdr s)
10                   (- n 1))))
11
12 (define (stream-map proc s)
13   (if (stream-null? s)
14       the-empty-stream
15       (cons-stream (proc (stream-car s))
16                    (stream-map proc (stream-cdr s)))))
17
18 (define (stream-filter pred? s)
19   (cond [(stream-null? s) the-empty-stream]
20         [(pred? (stream-car s))
21          (cons-stream (stream-car s)
22                       (stream-filter pred? (stream-cdr s)))]
23         [else (stream-filter pred? (stream-cdr s))]))
24
25 (define (stream-for-each proc s)
26   (if (stream-null? s)
27       'done
28       (begin
29         (proc (stream-car s))
30         (stream-for-each proc (stream-cdr s)))))
31
32 (define (display-stream s)
33   (stream-for-each display-line s))
34
35 (define (display-line x)
36   (newline)
37   (display x))
38
39 ;; stream-enumerate-interval
40 (define (stream-enumerate-interval low high)
41   (if (> low high)
42       the-empty-stream
43       (cons-stream low
44                    (stream-enumerate-interval (+ low 1)
45                                               high))))
46
47 #|
48
49 (define (show x)
50   (display-line x)
51   x)
52
53 (define x (stream-map show (stream-enumerate-interval 0 10)))
54
55 This will display 0. The reason is that, we can reduce this expression
56 to
57
58 (cons
59      (show (car 
60                 (cons 0 (delay (stream-enumerate-interval 1 10))))
61      (delay
62            (stream-map show (stream-cdr 
63                                        (cons 0 (delay (stream-enumerate-interval 1 10)))))))
64
65 This will print 0 and the rest of the computation is delayed.
66
67 (stream-ref x 5)
68
69 stream-ref will keep calling stream-cdr on the stream for 5 times. This will 'force' evaluation
70 of the delayed operations.
71
72 x is (cons 0
73            (delay (stream-map show (stream-enumerate-interval 1 10))))
74
75 Calling stream-cdr once, this expression becomes
76  (cons 0 
77        (cons-stream (show (stream-car (stream-enumerate-interval 1 10)))
78                     (stream-map show 
79                                 (stream-cdr (stream-enumerate-interval 1 10)))))
80
81
82
83  (cons 0
84        (cons 1 ;; also prints 1
85              (delay (stream-map show 
86                                 (stream-cdr (stream-enumerata-interval 1 10))))))
87
88 As can be seen, this will print 1 and the rest are 'delayed'.
89
90 Think of the output of (stream-enumerate-interval 0 10) as:
91
92 (cons 0 
93       (delay (cons 1
94                    (delay (cons 2
95                                 (delay (cons 3
96                                              (delay (cons 4
97                                                           .........
98                                                                    (delay (cons 10 the-empty-stream))...)
99
100 Let us call it s.
101
102 Now, x is (stream-map show s). This is equiv of:
103
104 (cons (show (stream-car s))
105       (delay (stream-map show (stream-cdr s)))
106
107 This will first print 0, when defined.
108
109 (stream-ref 5 x) is equiv to:
110
111 (stream-car (stream-cdr (stream-cdr (stream-cdr (stream-cdr (stream-cdr x))))))
112  
113 This will make the stream-map work on the 5 delayed computations and hence 
114 numbers from 1 to 5 printed on the screen. Together will that, the value of
115 (stream-ref s 5) == 5 will also be printed.
116
117 > (stream-ref x 7)
118
119 This will print 6 and 7 along with the value of the expression (i.e. 7).
120
121 |#
122
123 (define (show x)
124   (display-line x)
125   x)
126
127 (define x (stream-map show (stream-enumerate-interval 0 10)))
128 (stream-ref x 5)
129 (stream-ref x 7)
130