Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Midterm
n! =
Fn =
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
10
11
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
RCFAE: Interpreter
; interp : RCFAE DefrdSub -> RCFAE-Value (define (interp rcfae ds) (type-case RCFAE rcfae ... [rec (bound-id named-expr body-expr) ...]))
13
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
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
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
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
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
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
Boxes in DrScheme
A 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))
20
Example Run!
(run "{rec {count {fun {n} {if0 n 0 {+ 1 {count {- n 1}}}}}} {count 8}}" (mtSub))
21
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
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
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
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
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
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
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
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
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
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
Lazy Evaluation
32
33
Algebraic Shortcuts
In 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
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
36
{{fun {x} 0} {+ 1 {fun {y} 2}}} {{fun {x} x} {+ 1 {fun {y} 2}}}
37
{{fun {x} 0} {+ 1 {fun {y} 2}}} 0 {{fun {x} x} {+ 1 {fun {y} 2}}} error
38
Sukyoung Ryu
sryu.cs@kaist.ac.kr http://plrg.kaist.ac.kr