Presentation is loading. Please wait.

Presentation is loading. Please wait.

Closures and Streams cs784(Prasad) L11Clos

Similar presentations


Presentation on theme: "Closures and Streams cs784(Prasad) L11Clos"— Presentation transcript:

1 Closures and Streams cs784(Prasad) L11Clos
Great Reference: Abelson and Sussman : SICP Lecture introduces standard terms well-known in Functional Programming (languages) cs784(Prasad) L11Clos

2 Models of Evaluation Substitution-based (define (square x) (* x x))
((lambda (x y) (+ (square x) (square y))) (- 5 3) 5) (+ (square 2) (square 5)) (+ (* 2 2) (* 5 5)) ( ) 29 Equational reasoning by symbol manipulation; Arithmetic computation summarized without explicit rule invocation cs784(Prasad) L11Clos

3 Expression Evaluation Options
To evaluate: (operator operand1 operand2 operand3 ...) Applicative-Order Evaluation (call by value) evaluate each of the sub-expressions. apply the leftmost result to the rest. Normal-Order Evaluation (call by name) apply the leftmost (lambda) sub-expression to the rest and expand. (Argument sub-expressions get evaluated when necessary.) These two mechanisms differ substantially for the following case: ( (lambda (x) 5) ( (lambda (x) (x x)) (lambda (x) (x x)) ) ) When computation terminates, both approaches have give the same value. However, normal order evaluation has more propensity to terminate than application order evaluation. (E.g., an argument evaluation, whose value is actually not needed, may not terminate.) Work of Alonzo Church in the 30s cs784(Prasad) L11Clos

4 Models of Evaluation Environment-based ((lambda (x y)
(+ (square x) (square y))) (- 5 3) 5) (+ (square x) (square y)) x=2,y=5 (+ (* x x) x=2,y=5 (* x x) ) x=5,y=5 ( ) 29 Supports code reuse Substitution model specifies what to compute. Environment model computes it efficiently by only remembering those things that change. APPLICATIVE ORDER EVALUATION -- recursion no problem in substitution model cs784(Prasad) L11Clos

5 An extended example (define square (lambda (x) (* x x)))
(define sum-of-squares (lambda (x y) (+ (square x) (square y)))) (define f (lambda (a) (sum-of-squares (+ a 1) (* a 2)))) cs784(Prasad) L11Clos

6 Initial Global Environment
cs784(Prasad) L11Clos

7 Executing (f 5) and sum-of-squares
Static scoping: tree of environments Dynamic scoping: linear stack of environments cs784(Prasad) L11Clos

8 Delayed Evaluation : THUNKS
(define x (* 5 5)) x 25 (define y (lambda () (y) Partial Evaluation : CURRYING (define add (lambda (x) (lambda (y) (+ x y))) (define ad4 (add 4)) (ad4 8) 12 (define x 5) (define y (* x x)) (define x 6) y = 25 (define (y) (* x x)) (y) = 36 ML functions are inherently curried. Can consume arguments lazily. cs784(Prasad) L11Clos

9 Closure and Models < (lambda (y) Substitution (lambda (y) (+ 4 y) )
Substitution model is inadequate for mutable data structures. Environment < (lambda (y) (+ x y)) , [x <- 4] > Need to distinguish location and contents of the location. cs784(Prasad) L11Clos

10 Modular Designs with Lists
cs784(Prasad) L11Clos

11 Higher-order functions and lists
Use of lists and generic higher-order functions enable abstraction and reuse Can replace customized recursive definitions with more readable definitions built using “library” functions The HOF approach may be less efficient. Modular Designs using Lists cs784(Prasad) L11Clos

12 (define (even-fibs n) (define (next k) (if (> k n) () (let ((f (fib k)) (if (even? f) (cons f (next (+ k 1))) (next (+ k 1)) )) )) (next 0)) Take a number n and construct a list of first n even Fibonacci numbers. cs784(Prasad) L11Clos

13 Abstract Description enumerate integers from 0 to n
compute the Fibonacci number for each integer filter them, selecting even ones accumulate the results using cons, starting with () Instead of using dissimilar customized recursive definitions for the problems, understand their similarities, and exploit it by defining and reusing common primitives. cs784(Prasad) L11Clos

14 (define (filter pred seq) (cond ((null? seq) ()) ((pred (car seq))
(cons (car seq) (filter pred (cdr seq)))) (else (filter pred (cdr seq))) )) (define (accumulate op init seq) (if (null? seq) init (op (car seq) (accumulate op init (cdr seq))) Typically, init and op in accumulate are connected. init op x = x op init = x cs784(Prasad) L11Clos

15 (define (enum-interval low high) (if (> low high) ()
(cons low (enum-interval (+ low 1) high)) )) (define (even-fibs n) (accumulate cons nil (filter even? (map fib (enum-interval 0 n))))) cs784(Prasad) L11Clos

16 Streams: Motivation Streams simulated in Scheme and ML using closures. Streams are naturally supported through lazy evaluation in Haskell. For a classic account of streams refer to SICP (Abelson and Sussman) that clearly explains the following points: 1. Sequences and higher-order functions such as accumulate, map, filter, etc contribute to abstraction. 2. The need to support objects with states and assignments to have modular designs. (Problems with equality and sequencing.) 3. Streams as an alternative means to represent states through histories of values but without assignment. cs784(Prasad) L11Clos

17 Modeling real-world objects (with state) and real-world phenomena
Use computational objects with local variables and implement time variation of states using assignments Alternatively, use sequences to model time histories of the states of the objects. Possible Implementations of Sequences Using Lists Using Streams Delayed evaluation (demand-based evaluation) useful (necessary) when large (infinite) sequences are considered. cs784(Prasad) L11Clos

18 Streams : Equational Reasoning
(define s (cons 0 s)) Illegal. (Solution: infinite sequence of 0’s.) (0 . (0. (0. (0. … )))) (cf. Ada, Pascal,…) type s = record car : integer; cdr : s end; How do we represent potentially infinite structures? cs784(Prasad) L11Clos

19 (0.(0.(0. … ))) (0. Function which when (0. ) (0. ) (0. . . . )
executed generates an infinite structure ) Recursive winding and unwinding ( ) ( ) ( ) cs784(Prasad) L11Clos

20 >(define stream-car car) >(define (stream-cdr s) ( (cdr s) ) )
Unwrap by executing the second. >(define stream-zeros (cons 0 (lambda() stream-zeros) ) ) Wrap by forming closure (thunk). cs784(Prasad) L11Clos

21 (stream-cdr stream-zeros) ) >(define (numbers-from n) (cons n
>(stream-car (stream-cdr stream-zeros) ) >(define (numbers-from n) (cons n (lambda () (numbers-from (+ 1 n)) ))) >(define stream-numbers (numbers-from 0) ) cs784(Prasad) L11Clos

22 Recapitulating Stream Primitives
(define stream-car car) (define (stream-cdr s) ( (cdr s) ) ) (define (stream-cons x s) (cons x ( lambda ( ) s) ) ) (define the-empty-stream () ) (define stream-null? null?) These functions enable creation of streams with finite number of elements. For infinite streams, we need to use the technique given earlier for the seed-stream. cs784(Prasad) L11Clos

23 (define (stream-filter p s) (cond ((stream-null? s) the-empty-stream)
((p (stream-car s)) (stream-cons (stream-car s) (stream-filter p (stream-cdr s)))) (else (stream-filter p (stream-cdr s))) )) (define (stream-enum-interval low high) (if (> low high) the-empty-stream (stream-cons low (stream-enum-interval (+ 1 low) high)))) cs784(Prasad) L11Clos

24 (stream-enum-interval 100 1000))))
(stream-car (stream-cdr (stream-filter prime? (stream-enum-interval )))) (define (fibgen f1 f2) (cons f1 (lambda () (fibgen f2 (+ f1 f2))) )) (define fibs (fibgen 0 1)) Evaluate only as much as is necessary. Efficient. The following implementation is incorrect because of call by value evaluation. It would be okay in a lazy language. (define (fibgen f1 f2) (stream-cons f1 (fibgen f2 (+ f1 f2)) )) cs784(Prasad) L11Clos

25 Factorial Revisited (define (trfac n) (letrec ( (iter (lambda (i a)
(if (zero? i) a (iter (- i 1) (* a i))))) ) (iter n 1) tail recursive factorial that can be automatically translated into an iteration. cs784(Prasad) L11Clos

26 (define (ifac n) (let (( i n ) ( a 1 )) (letrec ( (iter (lambda ()
(if (zero? i) a (begin (set! a (* a i)) (set! i (- i 1)) (iter) )) ) (define (fac n) (let (( i n ) ( a 1 )) (letrec ( (iter (lambda () (if (zero? i) a (begin (set! i (- i 1)) (set! a (* a i)) (iter) )) ) (fac 4) = // ERROR The parallel assignment to formals is now made sequential. Because one of the formal effects the other, it is important that old values of a and i be used. Hence the ordering is constrained. There is also potential for bugs in rewriting tail-recursion as the corresponding iteration if ordering is messed-up. cs784(Prasad) L11Clos

27 Factorial Stream (define (str n r) (cons r (lambda ()
(str (+ n 1) (* n r)) ) (define sfac (str 1 1)) (car ((cdr ((cdr ((cdr sfac)) )) )) ) … (stream-cdr … ) Demand driven generation of list elements. Caching/Memoing necessary for efficiency. Avoids assignment. str (“n” , “factorial n-1” ) We remember factorial n-1 to minimize computation ,1,2,6,24,… To compute the i-th factorial, this seems only constant factor inefficient than the iterative loop for the amount of computation. cs784(Prasad) L11Clos


Download ppt "Closures and Streams cs784(Prasad) L11Clos"

Similar presentations


Ads by Google