--- /dev/null
+#lang planet neil/sicp
+
+(define (stream-car s) (car s))
+(define (stream-cdr s) (force (cdr s)))
+
+(define (stream-ref s n)
+ (if (= n 0)
+ (stream-car s)
+ (stream-ref (stream-cdr s)
+ (- n 1))))
+
+(define (stream-map proc s)
+ (if (stream-null? s)
+ the-empty-stream
+ (cons-stream (proc (stream-car s))
+ (stream-map proc (stream-cdr s)))))
+
+(define (stream-filter pred? s)
+ (cond [(stream-null? s) the-empty-stream]
+ [(pred? (stream-car s))
+ (cons-stream (stream-car s)
+ (stream-filter pred? (stream-cdr s)))]
+ [else (stream-filter pred? (stream-cdr s))]))
+
+(define (stream-for-each proc s)
+ (if (stream-null? s)
+ 'done
+ (begin
+ (proc (stream-car s))
+ (stream-for-each proc (stream-cdr s)))))
+
+(define (display-stream s)
+ (stream-for-each display-line s))
+
+(define (display-line x)
+ (newline)
+ (display x))
+
+;; stream-enumerate-interval
+(define (stream-enumerate-interval low high)
+ (if (> low high)
+ the-empty-stream
+ (cons-stream low
+ (stream-enumerate-interval (+ low 1)
+ high))))
+
+#|
+
+(define (show x)
+ (display-line x)
+ x)
+
+(define x (stream-map show (stream-enumerate-interval 0 10)))
+
+This will display 0. The reason is that, we can reduce this expression
+to
+
+(cons
+ (show (car
+ (cons 0 (delay (stream-enumerate-interval 1 10))))
+ (delay
+ (stream-map show (stream-cdr
+ (cons 0 (delay (stream-enumerate-interval 1 10)))))))
+
+This will print 0 and the rest of the computation is delayed.
+
+(stream-ref x 5)
+
+stream-ref will keep calling stream-cdr on the stream for 5 times. This will 'force' evaluation
+of the delayed operations.
+
+x is (cons 0
+ (delay (stream-map show (stream-enumerate-interval 1 10))))
+
+Calling stream-cdr once, this expression becomes
+ (cons 0
+ (cons-stream (show (stream-car (stream-enumerate-interval 1 10)))
+ (stream-map show
+ (stream-cdr (stream-enumerate-interval 1 10)))))
+
+=
+
+ (cons 0
+ (cons 1 ;; also prints 1
+ (delay (stream-map show
+ (stream-cdr (stream-enumerata-interval 1 10))))))
+
+As can be seen, this will print 1 and the rest are 'delayed'.
+
+Think of the output of (stream-enumerate-interval 0 10) as:
+
+(cons 0
+ (delay (cons 1
+ (delay (cons 2
+ (delay (cons 3
+ (delay (cons 4
+ .........
+ (delay (cons 10 the-empty-stream))...)
+
+Let us call it s.
+
+Now, x is (stream-map show s). This is equiv of:
+
+(cons (show (stream-car s))
+ (delay (stream-map show (stream-cdr s)))
+
+This will first print 0, when defined.
+
+(stream-ref 5 x) is equiv to:
+
+(stream-car (stream-cdr (stream-cdr (stream-cdr (stream-cdr (stream-cdr x))))))
+
+This will make the stream-map work on the 5 delayed computations and hence
+numbers from 1 to 5 printed on the screen. Together will that, the value of
+(stream-ref s 5) == 5 will also be printed.
+
+> (stream-ref x 7)
+
+This will print 6 and 7 along with the value of the expression (i.e. 7).
+
+|#
+
+(define (show x)
+ (display-line x)
+ x)
+
+(define x (stream-map show (stream-enumerate-interval 0 10)))
+(stream-ref x 5)
+(stream-ref x 7)
+
--- /dev/null
+#lang planet neil/sicp
+
+(define (stream-car s) (car s))
+(define (stream-cdr s) (force (cdr s)))
+
+(define (stream-ref s n)
+ (if (= n 0)
+ (stream-car s)
+ (stream-ref (stream-cdr s)
+ (- n 1))))
+
+(define (stream-map proc s)
+ (if (stream-null? s)
+ the-empty-stream
+ (cons-stream (proc (stream-car s))
+ (stream-map proc (stream-cdr s)))))
+
+(define (stream-filter pred? s)
+ (cond [(stream-null? s) the-empty-stream]
+ [(pred? (stream-car s))
+ (cons-stream (stream-car s)
+ (stream-filter pred? (stream-cdr s)))]
+ [else (stream-filter pred? (stream-cdr s))]))
+
+(define (stream-for-each proc s)
+ (if (stream-null? s)
+ 'done
+ (begin
+ (proc (stream-car s))
+ (stream-for-each proc (stream-cdr s)))))
+
+(define (display-stream s)
+ (stream-for-each display-line s))
+
+(define (display-line x)
+ (newline)
+ (display x))
+
+;; stream-enumerate-interval
+(define (stream-enumerate-interval low high)
+ (if (> low high)
+ the-empty-stream
+ (cons-stream low
+ (stream-enumerate-interval (+ low 1)
+ high))))
+
+#|
+
+(define sum 0)
+(define (accum x)
+ (set! sum (+ x sum))
+ sum)
+
+(define seq (stream-map accum (stream-enumerate-interval 1 20)))
+
+(define y (stream-filter even? seq))
+
+(define z (stream-filter (lambda (x) (= (remainder x 5) 0))
+ seq))
+
+(stream-ref y 7)
+
+(display-stream z)
+
+|#
+
+#|
+
+What is the value of sum after each of the above expressions is evaluated?
+
+ANS:
+
+> (define seq (stream-map accum (stream-enumerate-interval 1 20)))
+1
+
+This is because (stream-enumerate-interval 1 20) builds up a stream
+which looks as follows:
+
+s ==
+
+(cons 1
+ (delay (cons 2
+ (delay (cons 3
+ (delay .......)))..))
+
+Now, calling stream-map will produce seq which looks like this:
+
+seq == (cons (accum (car s)) ;; adds (car s) to sum
+ (delay (stream-map accum (stream-cdr s))))
+ == (cons 1
+ (delay (stream-map accum (stream-cdr s))))
+|#
+
+#|
+
+(define y (stream-filter even? seq))
+
+This will first run (even? (stream-car seq)) which will be false for
+the first value (i.e. 1). So, it will do:
+
+(stream-filter even? (stream-cdr seq))
+
+Calling stream-cdr on the seq will 'force' the delayed computation.
+So, seq becomes:
+
+seq == (cons 1
+ (stream-map accum (stream-cdr s)))
+ == (cons 1
+ (cons (accum 2) ;; sum becomes 3
+ (delay (stream-map accum (stream-cdr s)))))
+
+Now, stream-filter will be called with seq as:
+
+ (cons 3
+ (delay (stream-map accum (stream-cdr s))))
+
+Again, stream-filter will run the car of seq with the predicate:
+
+ (even? (car seq))
+
+which will be false; Now the new computation will be:
+
+ (cons (accum 3) ;; sum becomes 3 + 3 = 6
+ (delay (stream-map accum (stream-cdr s)))))
+
+When stream-filter runs the predicate, (even? (stream-car seq))
+it will return true. At this point, sum = 6.
+
+|#
+
+#|
+
+(define z (stream-filter (lambda (x) (= (remainder x 5) 0))
+ seq))
+
+At this point, seq is
+
+(1 (3 (6 (delay (stream-map accum (stream-cdr s)))))
+
+The forming of the new value of z will run it thru 1, 3 and 6
+and finds that they are not multiple of 5. Now, seq is
+
+(cons (accum 4) ;; sum = 6 + 4 = 10
+ (delay (stream-map accum (stream-cdr s))))
+
+=
+(cons 10
+ (delay (stream-map accum (stream-cdr s)))))
+
+Now, stream-filter will run the predicate and will return
+true and returns a stream-cons. At this point, sum = 10.
+
+|#
+
+#|
+
+(stream-ref y 7)
+
+This will take out 7 values out of y, which means 7 even values. So,
+we produce 16 values in the initial stream before we get 7 even values.
+
+(cons 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 (delay (cons 17 (delay (cons 18 ...))))
+
+sum should be
+(+ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16)
+= 136
+
+|#
+
+#|
+
+(display-stream z)
+
+If we were to evaluate seq as a whole and also the rest, we would
+get the following.
+
+seq is:
+
+(1 3 6 10 15 21 28 36 45 55 66 78 91 105 120 136 153 171 190 210)
+
+y is
+
+(10 28 36 66 78 120 136 190 210)
+
+z is
+
+(10 15 45 55 95 105 120 190 210)
+
+sum is 210
+
+|#
\ No newline at end of file
--- /dev/null
+#lang planet neil/sicp
+
+(define (stream-car s) (car s))
+(define (stream-cdr s) (force (cdr s)))
+
+(define (stream-ref s n)
+ (if (= n 0)
+ (stream-car s)
+ (stream-ref (stream-cdr s)
+ (- n 1))))
+
+(define (stream-map proc s)
+ (if (stream-null? s)
+ the-empty-stream
+ (cons-stream (proc (stream-car s))
+ (stream-map proc (stream-cdr s)))))
+
+(define (stream-filter pred? s)
+ (cond [(stream-null? s) the-empty-stream]
+ [(pred? (stream-car s))
+ (cons-stream (stream-car s)
+ (stream-filter pred? (stream-cdr s)))]
+ [else (stream-filter pred? (stream-cdr s))]))
+
+(define (stream-for-each proc s)
+ (if (stream-null? s)
+ 'done
+ (begin
+ (proc (stream-car s))
+ (stream-for-each proc (stream-cdr s)))))
+
+(define (display-stream s)
+ (stream-for-each display-line s))
+
+(define (display-line x)
+ (newline)
+ (display x))
+
+;; stream-enumerate-interval
+(define (stream-enumerate-interval low high)
+ (if (> low high)
+ the-empty-stream
+ (cons-stream low
+ (stream-enumerate-interval (+ low 1)
+ high))))
+
+
+;; prime?
+(define (square x) (* x x))
+(define (smallest-divisor n)
+ (find-divisor n 2))
+(define (find-divisor n test-divisor)
+ (cond ((> (square test-divisor) n) n)
+ ((divides? test-divisor n) test-divisor)
+ (else (find-divisor n (+ test-divisor 1)))))
+(define (divides? a b)
+ (= (remainder b a) 0))
+
+(define (prime? n)
+ (= (smallest-divisor n) n))
+