Top Banner
CS320: Recursion and Lazy Evaluation Sukyoung Ryu March 12, 2012 0
40
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript

CS320:

Recursion and Lazy EvaluationSukyoung RyuMarch 12, 2012

CS320: Recursion and Lazy Evaluation

Midterm

March 28th Wednesday 11AM1PM

1

CS320: Recursion and Lazy Evaluation

Questions and Answers Why do we learn recursion?

2

CS320: Recursion and Lazy Evaluation

Questions and Answers Why do we learn recursion? 1 (n 1)! n 0 1 F n1 + Fn2 if n = 0 if n > 0 if n = 0 if n = 1 if n > 1

n! =

Fn =

3

CS320: Recursion and Lazy Evaluation

Questions and Answers Why do we learn recursion in this way?

4

CS320: Recursion and Lazy Evaluation

Questions and Answers Why do we learn recursion in this way?Denition: a method where the solution to a problem depends on solutions to smaller instances of the same problem.a > Examples:factorial(n) = if n = 0 then 1 else factorial(n-1) * n fibonacci(n) = if n = 0 then 1 else if n = 1 then 1 else fibonacci(n-1) + fibonacci(n-2)> >

Interpreter: Dene a small language with recursion and implement its interpreter to see how it actually works.

L. Graham, Donald E. Knuth, and Oren Patashnik (1990). Concrete Mathematics. Chapter 1: Recurrent Problems.

a Ronald

5

CS320: Recursion and Lazy Evaluation

Questions and Answers Why do we learn recursion in this way? > Because DrRacket does not support recursion?

6

CS320: Recursion and Lazy Evaluation

Questions and Answers Why do we learn recursion in this way? > Because DrRacket does not support recursion?; interp : AE -> number (define (interp an-ae) (type-case AE an-ae [num (n) n] [add (l r) (+ (interp l) (interp r))] [sub (l r) (- (interp l) (interp r))]))

7

CS320: Recursion and Lazy Evaluation

Questions and Answers Why do we learn recursion in this way? > Why not just use recursion supported by DrRacket? Why bother use dummy values for functions?

8

CS320: Recursion and Lazy Evaluation

Questions and Answers Why do we learn recursion in this way? > Why not just use recursion supported by DrRacket? Why bother use dummy values for functions? > DrRacket denes recursive functions by define and RCFAE denes recursive functions by rec. > DrRacket looks up recursive functions from its internal symbol table and RCFAE looks up recursive functions from DefrdSub.

9

CS320: Recursion and Lazy Evaluation

RCFAE: Concrete Syntax ::= | {+ } | {- } | | {fun {} } | { } | {if0 } | {rec { } }

10

CS320: Recursion and Lazy Evaluation

RCFAE: Abstract Syntax(define-type RCFAE [num (n number?)] [add (lhs RCFAE?) (rhs RCFAE?)] [sub (lhs RCFAE?) (rhs RCFAE?)] [id (name symbol?)] [fun (param symbol?) (body RCFAE?)] [app (fun-expr RCFAE?) (arg-expr RCFAE?)] [if0 (test-expr RCFAE?) (then-expr RCFAE?) (else-expr RCFAE?)] [rec (name symbol?) (named-expr RCFAE?) (body RCFAE?)])

11

CS320: Recursion and Lazy Evaluation

RCFAE: Interpreter; interp : RCFAE DefrdSub -> RCFAE-Value (define (interp rcfae ds) (type-case RCFAE rcfae [num (n) (numV n)] [add (l r) (num+ (interp l ds) (interp r ds))] [sub (l r) (num- (interp l ds) (interp r ds))] [id (name) (lookup name ds)] [fun (param body-expr) (closureV param body-expr ds)] [app (f a) (local [(define ftn (interp f ds))] (interp (closureV-body ftn) (aSub (closureV-param ftn) (interp a ds) (closureV-ds ftn))))] [if0 (c t e) (if (numzero? (interp c ds)) (interp t ds) (interp e ds))] [rec (bound-id named-expr body-expr) ...]))

12

CS320: Recursion and Lazy Evaluation

RCFAE: Interpreter; interp : RCFAE DefrdSub -> RCFAE-Value (define (interp rcfae ds) (type-case RCFAE rcfae ... [rec (bound-id named-expr body-expr) ...]))

13

CS320: Recursion and Lazy Evaluation

RCFAE: Interpreter; interp : RCFAE DefrdSub -> RCFAE-Value (define (interp rcfae ds) (type-case RCFAE rcfae ... [rec (bound-id named-expr body-expr) ... (interp named-expr ds) ... (interp body-expr ds) ...]))

14

CS320: Recursion and Lazy Evaluation

RCFAE: Interpreter; interp : RCFAE DefrdSub -> RCFAE-Value (define (interp rcfae ds) (type-case RCFAE rcfae ... [rec (bound-id named-expr body-expr) (local [(define new-ds (aRecSub bound-id ... ds))] ... (interp named-expr new-ds) ... (interp body-expr new-ds) ...)]))

15

CS320: Recursion and Lazy Evaluation

RCFAE: Interpreter; interp : RCFAE DefrdSub -> RCFAE-Value (define (interp rcfae ds) (type-case RCFAE rcfae ... [rec (bound-id named-expr body-expr) (local [(define value-holder (box (numV 42))) (define new-ds (aRecSub bound-id value-holder ds))] ... (interp named-expr new-ds) ... (interp body-expr new-ds) ...]))

16

CS320: Recursion and Lazy Evaluation

RCFAE: Interpreter; interp : RCFAE DefrdSub -> RCFAE-Value (define (interp rcfae ds) (type-case RCFAE rcfae ... [rec (bound-id named-expr body-expr) (local [(define value-holder (box (numV 42))) (define new-ds (aRecSub bound-id value-holder ds))] (begin (set-box! value-holder (interp named-expr new-ds)) (interp body-expr new-ds)))]))

17

CS320: Recursion and Lazy Evaluation

RCFAE: DefrdSub(define-type DefrdSub [mtSub] [aSub (name symbol?) (value RCFAE-Value?) (ds DefrdSub?)] [aRecSub (name symbol?) (value-box (box/c RCFAE-Value?)) (ds DefrdSub?)]) (define-type RCFAE-Value [numV (n number?)] [closureV (param Symbol?) (body RCFAE?) (ds DefrdSub?)])

18

CS320: Recursion and Lazy Evaluation

RCFAE: Lookup; lookup : symbol DefrdSub -> num (define (lookup name ds) (type-case DefrdSub ds [mtSub () (error lookup "free variable")] [aSub (sub-name val rest-ds) (if (symbol=? sub-name name) val (lookup name rest-ds))] [aRecSub (sub-name val-box rest-ds) (if (symbol=? sub-name name) (unbox val-box) (lookup name rest-ds))]))

19

CS320: Recursion and Lazy Evaluation

Boxes in DrSchemeA box is like a single-element vector, normally used as minimal mutable storage. http://docs.racket-lang.org/reference/boxes.html box:(define value-holder (box (numV 42))) (set-box! value-holder (interp named-expr new-ds))

set-box!: unbox: box/c:

(unbox val-box) (value-box (box/c RCFAE-Value?))

20

CS320: Recursion and Lazy Evaluation

Example Run!

(run "{rec {count {fun {n} {if0 n 0 {+ 1 {count {- n 1}}}}}} {count 8}}" (mtSub))

21

CS320: Recursion and Lazy Evaluation

Example Run![rec (f fun-expr body) (local [(define value-holder (box (numV 42))) (define new-ds (aRecSub f value-holder ds))] (begin (set-box! value-holder (interp fun-expr new-ds)) (interp body new-ds)))] (run "{rec {count {fun {n} {if0 n 0 {+ 1 {count {- n 1}}}}}} {count 8}}" (mtSub))

22

CS320: Recursion and Lazy Evaluation

Example Run![rec (f fun-expr body) (local [(define value-holder (box (numV 42))) (define new-ds (aRecSub f value-holder ds))] (begin (set-box! value-holder (interp fun-expr new-ds)) (interp body new-ds)))] (run "{rec {count {fun {n} {if0 n 0 {+ 1 {count {- n 1}}}}}} {count 8}}" (mtSub)) f fun-expr body value-holder new-ds = = = = =23

CS320: Recursion and Lazy Evaluation

Example Run![rec (f fun-expr body) (local [(define value-holder (box (numV 42))) (define new-ds (aRecSub f value-holder ds))] (begin (set-box! value-holder (interp fun-expr new-ds)) (interp body new-ds)))] (run "{rec {count {fun {n} {if0 n 0 {+ 1 {count {- n 1}}}}}} {count 8}}" (mtSub)) f fun-expr body value-holder new-ds = = = = = "count" "{fun {n} {if0 n 0 {+ 1 {count {- n 1}}}}}" "{count 8}" [numV 42] (aRecSub count value-holder (mtSub))24

CS320: Recursion and Lazy Evaluation

Example Run![rec (f fun-expr body) (local [(define value-holder (box (numV 42))) (define new-ds (aRecSub f value-holder ds))] (begin (set-box! value-holder (interp fun-expr new-ds)) (interp body new-ds)))] (interp fun-expr new-ds) fun-expr body value-holder new-ds = = = = "{fun {n} {if0 n 0 {+ 1 {count {- n 1}}}}}" "{count 8}" [numV 42] (aRecSub count value-holder (mtSub))

25

CS320: Recursion and Lazy Evaluation

Example Run!

[fun (param body-expr) (closureV param body-expr ds)] (interp fun-expr new-ds) fun-expr body value-holder new-ds = = = = "{fun {n} {if0 n 0 {+ 1 {count {- n 1}}}}}" "{count 8}" [numV 42] (aRecSub count value-holder (mtSub))

26

CS320: Recursion and Lazy Evaluation

Example Run!

[fun (param body-expr) (closureV param body-expr ds)] (interp fun-expr new-ds) fun-expr = "{fun {n} {if0 n 0 {+ 1 {count {- n 1}}}}}" body = "{count 8}" value-holder = [numV 42] new-ds = (aRecSub count value-holder (mtSub)) (interp fun-expr new-ds) = (closureV n "{if0 n 0 {+ 1 {count {- n 1}}}}" new-ds)

27

CS320: Recursion and Lazy Evaluation

Example Run![rec (f fun-expr body) (local [(define value-holder (box (numV 42))) (define new-ds (aRecSub f value-holder ds))] (begin (set-box! value-holder (interp fun-expr new-ds)) (interp body new-ds)))] (interp fun-expr new-ds) fun-expr = "{fun {n} {if0 n 0 {+ 1 {count {- n 1}}}}}" body = "{count 8}" value-holder = [numV 42] new-ds = (aRecSub count value-holder (mtSub)) (interp fun-expr new-ds) = (closureV n "{if0 n 0 {+ 1 {count {- n 1}}}}" new-ds)

28

CS320: Recursion and Lazy Evaluation

Example Run![rec (f fun-expr body) (local [(define value-holder (box (numV 42))) (define new-ds (aRecSub f value-holder ds))] (begin (set-box! value-holder (interp fun-expr new-ds)) (interp body new-ds)))] (set-box! value-holder (interp fun-expr new-ds)) fun-expr = "{fun {n} {if0 n 0 {+ 1 {count {- n 1}}}}}" body = "{count 8}" value-holder = [numV 42] new-ds = (aRecSub count value-holder (mtSub)) (interp fun-expr new-ds) = (closureV n "{if0 n 0 {+ 1 {count {- n 1}}}}" new-ds)

29

CS320: Recursion and Lazy Evaluation

Example Run![rec (f fun-expr body) (local [(define value-holder (box (numV 42))) (define new-ds (aRecSub f value-holder ds))] (begin (set-box! value-holder (interp fun-expr new-ds)) (interp body new-ds)))] (set-box! value-holder (interp fun-expr new-ds)) fun-expr = "{fun {n} {if0 n 0 {+ 1 {count {- n 1}}}}}" body = "{count 8}" value-holder = [(closureV n "{if0 n 0 {+ 1 {count {- n 1}}}}" new-ds)] new-ds = (aRecSub count value-holder (mtSub)) (interp fun-expr new-ds) = (closureV n "{if0 n 0 {+ 1 {count {- n 1}}}}" new-ds)

30

CS320: Recursion and Lazy Evaluation

Example Run![rec (f fun-expr body) (local [(define value-holder (box (numV 42))) (define new-ds (aRecSub f value-holder ds))] (begin (set-box! value-holder (interp fun-expr new-ds)) (interp body new-ds)))] (interp body new-ds) fun-expr = "{fun {n} {if0 n 0 {+ 1 {count {- n 1}}}}}" body = "{count 8}" value-holder = [(closureV n "{if0 n 0 {+ 1 {count {- n 1}}}}" new-ds)] new-ds = (aRecSub count value-holder (mtSub)) (interp fun-expr new-ds) = (closureV n "{if0 n 0 {+ 1 {count {- n 1}}}}" new-ds)

31

CS320: Recursion and Lazy Evaluation

Lazy Evaluation

32

CS320: Recursion and Lazy Evaluation

Scheme vs. AlgebraIn Scheme, we have a specic order for evaluating subexpressions: (+ (* 4 3) (- 8 7)) (+ 12 (- 8 7)) (+ 12 1) In Algebra, order does not matter: (4 3) + (8 7) 12 + (8 7) 12 + 1 or: (4 3) + (8 7) (4 3) + 1 12 + 1

33

CS320: Recursion and Lazy Evaluation

Algebraic ShortcutsIn Algebra, if we see: f (x, y ) = x g (z ) = . . . f (17, g (g (g (g (g (18)))))) then we can go straight to: 17 because the result of all the g calls will not be used.

34

CS320: Recursion and Lazy Evaluation

Lazy Evaluation Languages like Scheme, Java, and C are called eager > An expression is evaluated when it is encountered Languages that avoid unnecessary work are called lazy > An expression is evaluated only if its result is needed

35

CS320: Recursion and Lazy Evaluation

LFAE = Lazy FAE ::= | | | | | {+ } {- } {fun {} } { }

36

CS320: Recursion and Lazy Evaluation

LFAE = Lazy FAE ::= | | | | | {+ } {- } {fun {} } { }

{{fun {x} 0} {+ 1 {fun {y} 2}}} {{fun {x} x} {+ 1 {fun {y} 2}}}

37

CS320: Recursion and Lazy Evaluation

LFAE = Lazy FAE ::= | | | | | {+ } {- } {fun {} } { }

{{fun {x} 0} {+ 1 {fun {y} 2}}} 0 {{fun {x} x} {+ 1 {fun {y} 2}}} error

38

Sukyoung [email protected] http://plrg.kaist.ac.kr