51
Closures and Streams More on Evaluations CS784(pm) 1

Closures and Streams

  • Upload
    hali

  • View
    40

  • Download
    0

Embed Size (px)

DESCRIPTION

Closures and Streams. More on Evaluations. Scheme Expressions. Constants: numbers, booleans . Variables: names for values. Created using the special form define Special forms have special rules for evaluation. Cannot be redefined - PowerPoint PPT Presentation

Citation preview

Page 1: Closures and Streams

1

Closures and Streams

More on Evaluations

CS784(pm)

Page 2: Closures and Streams

Scheme Expressions1. Constants: numbers, booleans.2. Variables: names for values. Created using the special form

define3. Special forms have special rules for evaluation.

a) Cannot be redefinedb) 15 “magic words”: and, begin, case, cond, define,

do, if, lambda, let, let*, letrec, or, quasiquote, quote, set!

c) a special form is not a first-class object like a procedure4. Combination: (operator operands)

a) "function calls" or b) "procedure applications."

2CS784(pm)

Page 3: Closures and Streams

Mantras of Scheme• Every expression has a value

– except for • errors, • infinite loops, and• define special form

• Computing the value of a combination(e0 e1 e2 …)– Compute all sub-expressions (in any order)– Apply the value of the first (e0) to the values of the rest– Applicative Order

• The value of a lambda expression is a procedure

3CS784(pm)

Page 4: Closures and Streams

4

Order Of Evaluation

• The order of evaluation turns out to be of central importance for the strength of the functional paradigm.

• In this lecture we will study the subject of evaluation order in the functional programming paradigm. This includes an introduction to infinite lists (streams) in Scheme.

CS784(pm)

Page 5: Closures and Streams

Referential Transparency

1. (3*F(a, b) + b) *(3*F(a, b) - c)2. let t be 3*F(a, b) in (t + b)*(t - c)• Are these two equivalent? Depends on the

Details of F(x, y).

CS784(pm) 5

Page 6: Closures and Streams

6

Referential Transparency

• “Equals can be replaced by equals” Two equal expressions can substitute each other without affecting the meaning of a functional program

• Makes it is possible to do natural program transformations without concern for side effects

• Does not rely on a particular notion of equality– Reference equality, shallow equality and deep equality

cannot be distinguished by functional means• Is a major contrast to imperative programming

CS784(pm)

Page 7: Closures and Streams

Distance Between Points

(define square (lambda (x) (* x x)))(define sum-of-squares (lambda (x y) (+ (square x) (square y)))) (define dist-between-points (lambda (x1 y1 x2 y2) (sqrt (sum-of-squares (- x1 x2) (- y1 y2)))))

7

Page 8: Closures and Streams

8

Substitution Model of Evaluation• No assignments; i.e., no set! Or its equivalent.• To apply a compound procedure to arguments, evaluate the

body of the procedure with each formal parameter replaced by the corresponding argument

((lambda (x y) (+ (square x) (square y))) (- 5 3) 5)= (+ (square 2) (square 5)) = (+ (* 2 2) (* 5 5))= (+ 4 25)= 29

CS784(pm)

Page 9: Closures and Streams

Substitution Model Example• the evaluated expressions have "**" before and after “**” them.

(dist-between-pts 1 1 4 5)(dist-between-pts 1 **1** 4 5)(dist-between-pts 1 **1** **4** 5) (dist-between-pts **1** **1** **4** 5) (**proc (x1 y1 x2 y2) (sqrt (sum-of-squares (- x1 x2) (- y1 y2)))** **1** **1** **4** 5) (**proc (x1 y1 x2 y2) (sqrt (sum-of-squares (- x1 x2) (- y1 y2)))** **1** **1** **4** **5**) (sqrt (sum-of-squares (- **1** **4**) (- **1** **5**))) (sqrt (sum-of-squares (**sub** **1** **4**) (- **1** **5**))) (sqrt (sum-of-squares **-3** (- **1** **5**))) (sqrt (sum-of-squares **-3** (**sub** **1** **5**))) (sqrt (sum-of-squares **-3** **-4**)) (sqrt (**proc (x y) (+ (square x) (square y))** **-3** **-4**)) (sqrt (+ (square **-3**) (square **-4**))) (sqrt (+ (square **-3**) (**proc (x) (* x x)** **-4**))) (sqrt (+ (square **-3**) (* **-4** **-4**))) (sqrt (+ (square **-3**) (**mul** **-4** **-4**))) (sqrt (+ (square **-3**) **16**)) (sqrt (**add** (square **-3**) **16**)) (sqrt (**add** (**proc (x) (* x x)** **-3**) **16**)) (sqrt (**add** (* **-3** **-3**) **16**)) (sqrt (**add** (**mul** **-3** **-3**) **16**)) (sqrt (**add** **9** **16**)) (sqrt **25**) (**sqrt** **25**) **5**

9CS784(pm)

Page 10: Closures and Streams

10

Applicative Order Evaluation

• (rator rand1 rand2 rand3 ...)• evaluate all

– rator rand1 rand2 rand3 ... – in any order

• apply the first value rator to the rest rand1 … . – Unless it is a special form.

• Scheme uses Applicative Order– This is the reason for having special forms.

• call by valueCS784(pm)

Page 11: Closures and Streams

11

Normal Order Evaluation

• (rator rand1 rand2 rand3 ...)• Fully expand, then reduce.

– apply the leftmost sub-expression to the rest and expand.

– Argument sub-expressions get evaluated when necessary. • Don't evaluate operands until they are needed

• call by nameCS784(pm)

Page 12: Closures and Streams

Normal Order Example

• Fully Expand:1. (sum-of-squares (+ 5 1) (* 6 2))2. (**proc (x y) (+ (square x) (square y))** (+ 5 1) (* 6 2))3. (+ (square (+ 5 1)) (square (* 6 2)))4. (+ (**proc (x) (* x x)** (+ 5 1)) (square (* 6 2)))5. (+ (* (+ 5 1) (+ 5 1)) (square (* 6 2)))6. (+ (* (+ 5 1) (+ 5 1)) (**proc (x) (* x x)** (* 6 2)))7. (+ (* (+ 5 1) (+ 5 1)) (* (* 6 2) (* 6 2)))

Notation: ** expansion **; also, ** reduction **

12CS784(pm)

Page 13: Closures and Streams

Normal Order Example• Fully Expanded, now reduce1. (+ (* (+ 5 1) (+ 5 1)) (* (* 6 2) (* 6 2)))2. (+ (* (**add** 5 1) (+ 5 1)) (* (* 6 2) (* 6 2)))3. (+ (* (**add** **5** 1) (+ 5 1)) (* (* 6 2) (* 6 2)))4. (+ (* (**add** **5** **1**) (+ 5 1)) (* (* 6 2) (* 6 2)))5. (+ (* **6** (+ 5 1)) (* (* 6 2) (* 6 2)))6. (+ (* **6** (+ 5 1)) (* (* **6** 2) (* 6 2)))7. (+ (* **6** (+ 5 1)) (* (**mul** **6** 2) (* 6 2)))8. (+ (* **6** (+ 5 1)) (* (**mul** **6** **2**) (* 6 2))) 9. (+ (* **6** (+ 5 1)) (* **12** (* 6 2)))10. (+ (* **6** (+ 5 1)) (* **12** (* 6 **2**)))11. (+ (* **6** (+ 5 1)) (* **12** (* **6** **2**)))12. (+ (* **6** (+ 5 1)) (* **12** (**mul** **6** **2**)))13. (+ (* **6** (+ 5 1)) (* **12** **12**))14. (+ (* **6** (+ 5 1)) (**mul** **12** **12**))15. (+ (* **6** (+ 5 1)) **144**)16. (+ (* **6** (+ **5** 1)) **144**) 17. (+ (* **6** (+ **5** **1**)) **144**)18. (+ (* **6** (**add** **5** **1**)) **144**)19. (+ (* **6** **6**) **144**)20. (+ (**mul** **6** **6**) **144**)21. (+ **36** **144**)22. (**add** **36** **144**)23. **180**

13CS784(pm)

Page 14: Closures and Streams

Comments on Normal Order• Normal is not as efficient as applicative.

– We needed to evaluate (+ 5 1) and (* 6 2) twice, instead of once each with applicative order.

• Normal is more likely to terminate than applicative• (define p (lambda () (p)))• (define test

(lambda (x y) (if (= x 0) 0 y)))

• (test 0 (p))– applicative order: infinite loop – normal order: returns 0.

14CS784(pm)

Page 15: Closures and Streams

Arbitrary Evaluation Order

• Sub expressions can be evaluated in an arbitrary order provided that – no errors occur in sub expressions– the evaluation of every sub expression

terminates• Sub expressions can be evaluated in

parallel

CS784(pm) 15

Page 16: Closures and Streams

Strict v. Non-Strict

(define (inf-calc)(inf-calc))((lambda (x) 1) (inf-calc))• Different evaluation orders give different 'results'

– The number 1– A non-terminating calculation

• Two different semantics of function application:– Strict: A function call is well-defined if and only if all actual

parameters are well-defined– Non-strict: A function call can be well-defined even if one or

more actual parameters cause an error or an infinite calculation

CS784(pm) 16

Page 17: Closures and Streams

Normal- v. Applicative-Order

• Scheme and ML use applicative-order reduction• Haskell uses normal-order reduction• Normal-order reduction is more powerful than

the applicative-order reduction– If an expression e somehow can be reduced to f in

one or more steps, • e can be reduced to f by normal order reduction, but • not necessarily by applicative order reduction

CS784(pm) 17

Page 18: Closures and Streams

18

Special Forms• Forms for which applicative order reduction would not make

sense• (if b x y)

– Depending on the value of b, either x or y are evaluated– It would often be harmful to evaluate both x and y before the selection

• (define (fak n) (if (= n 0) 1 (* n (fak (- n 1)))))• (and x y z)

– and evaluates its parameter from left to right – In case x is false, there is no need to evaluate y and z– Often, it would be harmful to evaluate y and z

• (and (not (= y 0)) (even? (quotient x y)))

CS784(pm)

Page 19: Closures and Streams

19

Models

• Substitution model specifies what to compute.

• (lambda (y) (+ 4 y))

• Substitution model is inadequate for mutable data structures.

• Environment model computes it efficiently by only remembering those things that change.

• <(lambda (y) (+ x y)), [x := 4]>• We need to distinguish location and

contents of the location.

CS784(pm)

Page 20: Closures and Streams

Environments in Evaluation

((lambda (x y) (+ (square x)

(square y))) (- 5 3) 5)

= (+ (square x) (square y))

= (+ (* x x) (* x x))= (+ 4 25)= 29

20

x=2,y=5

x=2,y=5

x=5,y=5

CS784(pm)

Page 21: Closures and Streams

21

Closure

• A closure is an implementation technique for representing procedures with free variables.

• A closure is a data structure containing the argument expression and the environment

CS784(pm)

Page 22: Closures and Streams

22

An 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(pm)

Page 23: Closures and Streams

23

Initial Global Environment

CS784(pm)

Page 24: Closures and Streams

Executing (f 5) and sum-of-squares

24CS784(pm)

Page 25: Closures and Streams

25

Higher-order Functions And Lists

• Use of lists and generic higher-order functions (HOF) enable abstraction and reuse

• Can replace customized recursive definitions with more readable definitions built using “library” functions– The HOF approach may be less efficient.

• HOF Ex: map, filter, accumulateCS784(pm)

Page 26: Closures and Streams

26

Even Fibonacci Numbers• enumerate integers i from 0 to n• compute the i-th Fibonacci number for

each integer i• filter them, selecting even ones• accumulate the results using cons,

starting with ()

CS784(pm)

Page 27: Closures and Streams

Even Fibonacci Numbers

(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)))27CS784(pm)

Page 28: Closures and Streams

Filter

(define (filter pred seq) (cond ((null? seq) ()) ((pred (car seq)) (cons (car seq) (filter pred (cdr seq)))) (else (filter pred (cdr seq)))))

CS784(pm) 28

Page 29: Closures and Streams

Accumulate

(define (accumulate op init seq) (if (null? seq) init (op (car seq) (accumulate op init

(cdr seq)))))

• Typically, (op init x) = (op x init) = x

CS784(pm) 29

Page 30: Closures and Streams

Even Fibonacci Numbers

(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)))))

30CS784(pm)

Page 31: Closures and Streams

31

Lazy Evaluation• Delaying evaluation of expressions until they are needed

– Opposite: eager evaluation.• If the argument is evaluated before the body of the procedure is

entered we say that the procedure is strict in that argument.– In a purely applicative-order language, all procedures are strict in each

argument.– In a purely normal-order language, all procedures are non-strict in each

argument, and primitive procedures may be either strict or non-strict.• Lazy evaluation is one evaluation strategy used to implement

non-strict functions.• http://foldoc.org/lazy+evaluation

CS784(pm)

Page 32: Closures and Streams

Delayed evaluation in Scheme

• Scheme does not support normal-order reduction nor lazy evaluation.

• Scheme has an explicit primitive which delays an evaluation

• (delay expr) => promise R5RS: delay• (force promise) => value R5RS: force

CS784(pm) 32

Page 33: Closures and Streams

Use of Non-Strictness

• Non-strictness is useful in almost any constructor for data structures.– cons, in particular– E.g., compute the length of a list without knowing the

values of the individual elements in the list.– A language can control the strictness of each

argument.• (define (f a (b lazy) c (d lazy-memo)) ...)• Memoizing means that if an expression's value is needed more than once (i.e.,

it is shared), the result of the first evaluation is remembered and subsequent requests for it will return the remembered value.

CS784(pm) 33

Page 34: Closures and Streams

Interpreter with Lazy Evaluation

• Thunk– The delayed arguments/ operands are not evaluated;

instead, they are transformed into objects called thunks.– Represented as a closure - a data structure containing

• the argument expression and • the environment

• An operand is frozen when it is passed unevaluated to the procedure

• It is thawed when the procedure evaluates it.– The process of thawing is also called forcing.

CS784(pm) 34

Page 35: Closures and Streams

Streams

• Def: Streams Are Lazy Lists/ Sequences– As a data abstraction, streams are the same as lists.

• Lazy Evaluation– Lists: cdr is evaluated at construction time. – Streams: cdr is evaluated at selection time– construct a stream only partially, and– pass the partial construction to the program that

consumes the stream.• http://docs.racket-lang.org/srfi-std/srfi-41/srfi-41.html

35CS784(pm)

Page 36: Closures and Streams

Uses of Streams

• 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(pm) 36

Page 37: Closures and Streams

Potentially Infinite Structures• (define s (cons 0 s))• Solution: infinite sequence of zeros.(0 . (0. (0. (0. … ))))

• Illegal in ordinary Scheme.• cf. Ada, Pascal,…

type s = record

car: integer; cdr: s end;

37CS784(pm)

Page 38: Closures and Streams

Recursive Winding And Unwinding

• (0.(0.(0. … )))• (0.Function which when executed

generates next item of an infinite structure)– (0. )– (0.(0. ))– (0.(0.(0. . . . )))

38CS784(pm)

Page 39: Closures and Streams

Stream Primitives

• Constructor: stream-cons• Selectors

– stream-car– stream-cdr– (stream-car (stream-cons x y)) = x– (stream-cdr (stream-cons x y)) = y

• empty-stream• stream-null?

CS784(pm) 39

Page 40: Closures and Streams

Stream Primitives Implemented

•(define the-empty-stream ())•(define stream-null? null?)•(define stream-car car)•(define (stream-cdr s) ((cdr s)))•(define (stream-cons x s) (cons x (lambda () s)))•(require srfi/41)• SRFI = Scheme Requests For Implimentation• http://docs.racket-lang.org/srfi-std/srfi-41/srfi-41.html

40CS784(pm)

Page 41: Closures and Streams

Stream Examples

(define stream-zeros (cons 0 (lambda() stream-zeros)))

(define (numbers-from n) (cons n

(lambda ()(numbers-from (+ 1 n)))))

(define stream-numbers (numbers-from 0))

41CS784(pm)

Page 42: Closures and Streams

stream-enum-interval(define (stream-enum-interval low high) (if (> low high) the-empty-stream (stream-cons low (stream-enum-interval

(+ 1 low) high))))• (stream-enumerate-interval 10000 1000000)

– returns a stream represented as a pair • whose car is 10000 and • whose cdr is a promise to

– enumerate the next number and – a promise to …

CS784(pm) 42

Page 43: Closures and Streams

Stream Primitives -- More

(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)))))• Example(stream-car (stream-cdr (stream-filter prime? (stream-enum-interval 100 1000))))

43CS784(pm)

Page 44: Closures and Streams

Generate Fibonacci Numbers

Evaluate only as much as is necessary. Efficient.

(define (fibgen a b) (cons a (lambda () (fibgen b (+ a b)))))

(define fibs (fibgen 0 1))

CS784(pm) 44

Page 45: Closures and Streams

Generate Fibonacci Numbers

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))))

Page 46: Closures and Streams

Factorial Revisited

• Tail recursion that can be automatically translated into an iteration.

(define (trfac n) (letrec ((iter

(lambda (i a) (if (zero? i) a (iter (- i 1) (* a i))))))

(iter n 1)))

46CS784(pm)

Page 47: Closures and Streams

Factorial using Assignments

(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))))))

(iter))))47CS784(pm)

Page 48: Closures and Streams

Factorial Stream

(define (str n r) (cons r (lambda () (str (+ n 1) (* n r)))))(define sfac (str 1 1)) • (car ((cdr ((cdr ((cdr sfac)))))))• Demand driven generation of list elements.

Caching/ Memoing (of r) necessary for efficiency. Avoids assignment.

CS784(pm) 48

Page 49: Closures and Streams

The Sieve of Eratosthenes(define (sieve stream) (stream-cons (stream-car stream) (sieve (stream-filter (lambda (x) (not (divisible? x (stream-car stream)))) (stream-cdr stream)))))

CS784(pm) 49

Page 50: Closures and Streams

Sieve Of Eratosthenes

(define (divisible? x y)(= (remainder x y) 0))

(define (integers-starting-from n) (cons-stream n (integers-starting-from (+ n 1))))

(define primes (sieve (integers-starting-from 2)))

CS784(pm) 50

Page 51: Closures and Streams

51

References

• Structure and Interpretation of Computer Programs http://mitpress.mit.edu/sicp/ – 1.3 Abstractions w/ Higher-Order Procedures– 3.2 The Environment Model of Evaluation– 3.5 Streams– 4.2 Variations on a Scheme – Lazy Evaluation

• http://www.cs.aau.dk/~normark/prog3-03/html/notes/

• http://foldoc.org/lazy+evaluation CS784(pm)