From 7ce42a62ad95e3f833efe22b8b5d3c8f8e46e85e Mon Sep 17 00:00:00 2001 From: Correl Roush Date: Thu, 30 Oct 2014 22:26:07 -0400 Subject: [PATCH] 3.5 WIP --- 3-5.org | 300 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 300 insertions(+) create mode 100644 3-5.org diff --git a/3-5.org b/3-5.org new file mode 100644 index 0000000..b08b118 --- /dev/null +++ b/3-5.org @@ -0,0 +1,300 @@ +#+TITLE: 3.5 - Streams + +#+BEGIN_HTML + +#+END_HTML + +* Streams are Delayed Lists +#+begin_src scheme + (define (cons-stream a b) + (cons a (delay b))) + + (define (stream-car s) + (car s)) + + (define (stream-cdr s) + (force (cdr s))) + + (define the-empty-stream '()) + + (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-for-each proc s) + (if (stream-null? s) + 'done + (begin (proc (stream-car s)) + (stream-for-each proc (stream-cdr s))))) +#+end_src + +#+begin_src scheme :tangle yes + ;; =================================================================== + ;; 3.5.1: Streams are Delayed Lists + ;; =================================================================== + + (define (display-stream s) + (stream-for-each display-line s)) + + (define (display-line x) + (newline) + (display x)) + + (define (stream-enumerate-interval low high) + (if (> low high) + the-empty-stream + (cons-stream + low + (stream-enumerate-interval (+ low 1) high)))) + + (define (stream-filter pred stream) + (cond ((stream-null? stream) the-empty-stream) + ((pred (stream-car stream)) + (cons-stream (stream-car stream) + (stream-filter pred + (stream-cdr stream)))) + (else (stream-filter pred (stream-cdr stream))))) + + #+end_src + +** Exercise 3.50 +Complete the following definition, which generalizes `stream-map' to +allow procedures that take multiple arguments, analogous to `map' in +section *Note 2-2-3::, footnote *Note Footnote 12::. + +#+begin_src scheme + (define (stream-map proc . argstreams) + (if ( (car argstreams)) + the-empty-stream + ( + (apply proc (map argstreams)) + (apply stream-map + (cons proc (map argstreams)))))) +#+end_src + +---------------------------------------------------------------------- + +#+begin_src scheme + ;; ------------------------------------------------------------------- + ;; Exercise 3.50 + ;; ------------------------------------------------------------------- + + (define (stream-map proc . argstreams) + (if (stream-null? (car argstreams)) + the-empty-stream + (cons-stream + (apply proc (map stream-car argstreams)) + (apply stream-map + (cons proc (map stream-cdr argstreams)))))) +#+end_src + +** Exercise 3.51 +In order to take a closer look at delayed +evaluation, we will use the following procedure, which simply +returns its argument after printing it: + +#+begin_src scheme + (define (show x) + (display-line x) + x) +#+end_src + +What does the interpreter print in response to evaluating each +expression in the following sequence?(7) + +#+begin_src scheme + (define x (stream-map show (stream-enumerate-interval 0 10))) + + (stream-ref x 5) + + (stream-ref x 7) +#+end_src scheme + +---------------------------------------------------------------------- + +#+begin_src scheme + (define x (stream-map show (stream-enumerate-interval 0 10))) + ; 9 + ; 8 + ; 7 + ; 6 + ; 5 + ; 4 + ; 3 + ; 2 + ; 1 + ; 0 + ;Value: x + + (stream-ref x 5) + ;Value: 5 + + (stream-ref x 7) + ;Value: 7 + +#+end_src +** Exercise 3.52 +Consider the sequence of expressions + +#+begin_src scheme + (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) +#+end_src + +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 )' simply as `(lambda () +)' without using the optimization provided by `memo-proc'? +Explain + +---------------------------------------------------------------------- + +#+begin_example + 1 ]=> sum + ;Value: 210 + + 1 ]=> (stream-head y 10) + + ;Value 18: (210 204 200 182 174 144 132 90 74 20) + + 1 ]=> (display-stream z) + + 210 + 200 + 195 + 165 + 155 + 105 + 90 + 20 + ;Value: done +#+end_example + +After the definition of =seq=, =sum= is equal to 210. It remains at +210 through the remainder of the operations.This would not be the +case if delay were not memoized, as without being so it would be +recalculated each time the items in the node were resolved, adding to +the value of =sum= each time, and changing the results captured by =y= +and =z=. +* 3.5.2 Infinite Streams +#+begin_src scheme :tangle yes + ;; =================================================================== + ;; 3.5.2: Infinite Streams + ;; =================================================================== + + (define (integers-starting-from n) + (cons-stream n (integers-starting-from (+ n 1)))) + + (define integers (integers-starting-from 1)) + + (define (divisible? x y) (= (remainder x y) 0)) + + (define no-sevens + (stream-filter (lambda (x) (not (divisible? x 7))) + integers)) + + (define (fibgen a b) + (cons-stream a (fibgen b (+ a b)))) + + (define fibs (fibgen 0 1)) + + (define (sieve stream) + (cons-stream + (stream-car stream) + (sieve (stream-filter + (lambda (x) + (not (divisible? x (stream-car stream)))) + (stream-cdr stream))))) + + (define primes (sieve (integers-starting-from 2))) +#+end_src +** Defining streams implicitly +#+begin_src scheme :tangle yes + (define ones (cons-stream 1 ones)) + + (define (add-streams s1 s2) + (stream-map + s1 s2)) + + (define integers (cons-stream 1 (add-streams ones integers))) + + (define fibs + (cons-stream 0 + (cons-stream 1 + (add-streams (stream-cdr fibs) + fibs)))) + (define (scale-stream stream factor) + (stream-map (lambda (x) (* x factor)) stream)) + + (define double (cons-stream 1 (scale-stream double 2))) + + (define primes + (cons-stream + 2 + (stream-filter prime? (integers-starting-from 3)))) + + (define (prime? n) + (define (iter ps) + (cond ((> (square (stream-car ps)) n) true) + ((divisible? n (stream-car ps)) false) + (else (iter (stream-cdr ps))))) + (iter primes)) +#+end_src +*** Exercise 3.53 +Without running the program, describe the elements of the stream +defined by + +#+begin_src scheme + (define s (cons-stream 1 (add-streams s s))) +#+end_src + +---------------------------------------------------------------------- + +\[ +\sum_{i=1}^\infty 2^i +\] +*** Exercise 3.54 +Define a procedure `mul-streams', analogous to `add-streams', that +produces the elementwise product of its two input streams. Use this +together with the stream of `integers' to complete the following +definition of the stream whose nth element (counting from 0) is n + 1 +factorial: + +#+begin_src scheme + (define factorials (cons-stream 1 (mul-streams ))) +#+end_src + +---------------------------------------------------------------------- + +#+begin_src scheme :tangle yes + (define (mul-streams s1 s2) + (stream-map * s1 s2)) + + (define factorials (cons-stream 1 (mul-streams (add-streams ones integers) factorials))) +#+end_src +*** Exercise 3.55 +Define a procedure `partial-sums' that takes as argument a stream S +and returns the stream whose elements are S_0, S_0 + S_1, S_0 + S_1 + +S_2, .... For example, `(partial-sums integers)' should be the stream +1, 3, 6, 10, 15, ....