3.5 with notes

This commit is contained in:
Correl Roush 2014-11-17 20:15:04 -05:00
parent 7ce42a62ad
commit 4b9cf9c38b

122
3-5.org
View file

@ -1,4 +1,5 @@
#+TITLE: 3.5 - Streams #+TITLE: 3.5 - Streams
#+STARTUP: indent
#+BEGIN_HTML #+BEGIN_HTML
<script type="text/javascript" <script type="text/javascript"
@ -7,6 +8,30 @@
#+END_HTML #+END_HTML
* Streams are Delayed Lists * Streams are Delayed Lists
** Notes
#+BEGIN_SRC scheme
(define x (delay 5))
;; is equivalent to
(define x (lambda () 5))
;; A "thunk" (a function of no arguments, used to delay evaluation of its return value)
(force x)
;; => 5
#+END_SRC
The MIT implementation of =delay= returns a =promise= value. Force
will evaluate a =promise= if it hasn't yet been computed. The result
of the evaluation will be memoized for future calls to force.
Stream processing explanation: [[https://www.youtube.com/watch?v%3Da2Qt9uxhNSM#t%3D48m00s][MIT OpenCourseWare Lecture 6A]]
A stream a sequence built as a pair of an initial value, and a
procedure to generate the next value and the next procedure to
continue the sequence.
** Code
#+begin_src scheme #+begin_src scheme
(define (cons-stream a b) (define (cons-stream a b)
(cons a (delay b))) (cons a (delay b)))
@ -66,7 +91,8 @@
#+end_src #+end_src
** Exercise 3.50 ** Exercises
*** Exercise 3.50
Complete the following definition, which generalizes `stream-map' to Complete the following definition, which generalizes `stream-map' to
allow procedures that take multiple arguments, analogous to `map' in allow procedures that take multiple arguments, analogous to `map' in
section *Note 2-2-3::, footnote *Note Footnote 12::. section *Note 2-2-3::, footnote *Note Footnote 12::.
@ -97,7 +123,7 @@ section *Note 2-2-3::, footnote *Note Footnote 12::.
(cons proc (map stream-cdr argstreams)))))) (cons proc (map stream-cdr argstreams))))))
#+end_src #+end_src
** Exercise 3.51 *** Exercise 3.51
In order to take a closer look at delayed In order to take a closer look at delayed
evaluation, we will use the following procedure, which simply evaluation, we will use the following procedure, which simply
returns its argument after printing it: returns its argument after printing it:
@ -123,26 +149,24 @@ expression in the following sequence?(7)
#+begin_src scheme #+begin_src scheme
(define x (stream-map show (stream-enumerate-interval 0 10))) (define x (stream-map show (stream-enumerate-interval 0 10)))
; 9
; 8
; 7
; 6
; 5
; 4
; 3
; 2
; 1
; 0 ; 0
;Value: x ;Value: x
(stream-ref x 5) (stream-ref x 5)
1
2
3
4
5
;Value: 5 ;Value: 5
(stream-ref x 7) (stream-ref x 7)
6
7
;Value: 7 ;Value: 7
#+end_src #+end_src
** Exercise 3.52 *** Exercise 3.52
Consider the sequence of expressions Consider the sequence of expressions
#+begin_src scheme #+begin_src scheme
@ -198,7 +222,13 @@ 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 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= the value of =sum= each time, and changing the results captured by =y=
and =z=. and =z=.
* 3.5.2 Infinite Streams * Infinite Streams
** Notes
Streams can continue forever if the promise never returns an empty
stream.
Streams can be combined to model complex sequences.
** Code
#+begin_src scheme :tangle yes #+begin_src scheme :tangle yes
;; =================================================================== ;; ===================================================================
;; 3.5.2: Infinite Streams ;; 3.5.2: Infinite Streams
@ -230,7 +260,7 @@ and =z=.
(define primes (sieve (integers-starting-from 2))) (define primes (sieve (integers-starting-from 2)))
#+end_src #+end_src
** Defining streams implicitly *** Defining streams implicitly
#+begin_src scheme :tangle yes #+begin_src scheme :tangle yes
(define ones (cons-stream 1 ones)) (define ones (cons-stream 1 ones))
@ -261,6 +291,7 @@ and =z=.
(else (iter (stream-cdr ps))))) (else (iter (stream-cdr ps)))))
(iter primes)) (iter primes))
#+end_src #+end_src
** Exercises
*** Exercise 3.53 *** Exercise 3.53
Without running the program, describe the elements of the stream Without running the program, describe the elements of the stream
defined by defined by
@ -298,3 +329,66 @@ 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 + 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 S_2, .... For example, `(partial-sums integers)' should be the stream
1, 3, 6, 10, 15, .... 1, 3, 6, 10, 15, ....
* Exploiting the Stream Paradigm
** Notes
Streams and their property of delayed evaluation can be used to build
abstractions over the sequences and computations used to generate
them. The examples are the square-root stream and the pi streams being
accelerated via a generic stream transformation method.
* Streams and Delayed Evaluation
** Notes
#+BEGIN_QUOTE
...stream models of systems with loops may require uses of delay
beyond the “hidden” delay supplied by cons-stream.
#+END_QUOTE
#+BEGIN_QUOTE
Unfortunately, including delays in procedure calls wreaks havoc with
our ability to design programs that depend on the order of events,
such as programs that use assignment, mutate data, or perform input or
output.
...
As far as anyone knows, mutability and delayed evaluation do not mix
well in programming languages, and devising ways to deal with both of
these at once is an active area of research.
#+END_QUOTE
* Modularity of Functional Programs and Modularity of Objects
** Notes
Random number generation can be implemented as an infinite stream
instantiated with some seed.
*** A functional-programming view of time
#+BEGIN_QUOTE
We can model a changing quantity, such as the local state of some
object, using a stream that represents the time history of successive
states. In essence, we represent time explicitly, using streams, so
that we decouple time in our simulated world from the sequence of
events that take place during evaluation.
#+END_QUOTE
Events over time can be merged / serialized (deterministically?) into
a stream of events.
#+BEGIN_QUOTE
This is precisely the same constraint that we had to deal with in
3.4.1, where we found the need to introduce explicit synchronization
to ensure a “correct” order of events in concurrent processing of
objects with state. Thus, in an attempt to support the functional
style, the need to merge inputs from different agents reintroduces the
same problems that the functional style was meant to eliminate.
#+END_QUOTE
With a working merge solution, a system can be designed in a
functional way, operating on a stream of state and inputs.
The Erlang/OTP generic server, generic fsm and other behaviours are
implemented in such a way that input streams received concurrently are
merged by the vm and combined with the state of the process as a
single stream pairing the current state with the next input to
process, allowing an Erlang developer to build a functional interface
with the complexities of concurrency abstracted away.