Presentation is loading. Please wait.

Presentation is loading. Please wait.

Assignments and Procs w/Params

Similar presentations


Presentation on theme: "Assignments and Procs w/Params"— Presentation transcript:

1 Assignments and Procs w/Params
cs784(tk)

2 Assignment, LHS := RHS l-value: left-, location, address, reference, …
r-value: right-, int, real, address, … env and store allow one to describe the semantics of assignment in a purely functional style. (DENOTATIONAL SEMANTICS) Object language structures are mapped to similar Scheme structures. (META-CIRCULAR INTERPRETER) cs784(tk)

3 Sharing sharing/aliasing Point p = Point q = p; call by reference
new Point(); Point q = p; call by reference void f(Point p){…}; f(q); a loc value x cs784(tk)

4 Side-effects in Scheme
Update variable: (set! var exp) denotes location denotes value In Scheme locations are denotable, but not expressible Sequencing: (begin exp1 exp2 … expn) Ordering of expressions important cs784(tk)

5 Expressible vs. Denotable values
Expressible Values the language can express and compute these represented in the language's syntax as expressions Denotable Values represented in syntax by declarations the names and their values saved within a data structure (called a namespace or environment or symbol table or activation record) In some languages, these two are not equal. CS784 SchemeRefresher 5

6 Expressible vs. Denotable values
Booleans are expressible in (early) FORTRAN, but not denotable. Functions are denotable in many languages, but are not expressible. In (functional subset of) Scheme, both value spaces are identical. In (full) Scheme, variable references (pointers) are denotable but not expressible. CS784 SchemeRefresher

7 Local Binding: let (let proc-id ([id init-expr] ...) body ...+)
Defines a local procedure. Evaluates the init-exprs; these become arguments to the proc. The ids must be distinct. (let fac ([n 10]) (if (zero? n) 1 (* n (fac (sub1 n)))))  CS784 SchemeRefresher

8 Local Binding: let* (let* ([id val-expr] ...) body ...+)
Similar to let, but evaluates the val-exprs one by one, creating a location for each id as soon as the value is available. The ids are bound in the remaining val-exprs as well as the bodys, and the ids need not be distinct; later bindings shadow earlier bindings. (let* ([x 1] [y (+ x 1)]) (list y x))  (2 1) CS784 SchemeRefresher

9 Local Binding: letrec (letrec ([id val-expr] ...) body ...+)
Similar to let, but the locations for all ids are created first and filled with #<undefined>, and all ids are bound in all val-exprs as well as the bodys. The ids must be distinct. (letrec ((a b) (b 34) (c (+ b 5))) (list a b c))  (#<undefined> ) (letrec ([is-even? (lambda (n) (or (zero? n) (is-odd? (sub1 n))))] [is-odd? (lambda (n) (and (not (zero? n)) (is-even? (sub1 n))))]) (is-odd? 11))  #t CS784 SchemeRefresher

10 Comparison: let, let*, letrec
(let/let*/letrec ((v1 e1 ) (v2 e2 ) … (vn en )) body ) let no vi is created until all ei are evaluated. none of ei can refer to any vi let* e1 is evaluated; v1 created, bound to e1; e2 is evaluated; v2 created, bound to e2; …; ej can refer to earlier vi, i < j. letrec vi are created with #undefined as their value. with the above in effect, e1, …, en are evaluated l-to-r each vi is now bound to ei CS784 SchemeRefresher

11 Simulating Scheme letrec
(letrec ((v1 exp1) (v2 exp2)) exp) ;; exp1 and exp2 are lambda-forms (let ((v1 ’*) (v2 ’*)) (set! v1 exp1) (set! v2 exp2) exp ) let and assignment in the object language can allow us to simulate letrec, but only in the context of procedural values. (letrec ( (x (lambda () y)) (y 1) ) (x) ) = but (letrec ( (x y) (y 1) ) x ) = error cs784(tk)

12 Env and Store For functional subset, it is sufficient to model env as a function from ids to values. For imperative programming that has both assignment and sharing, separating env and store is necessary. env: identifier  location store: location  value assignment: location x value x store  store cs784(tk)

13 Our assignment, set var = exp
Concrete Syntax: set identifier = expression AST: varassign-exp (id rhs-exp) Semantics: add a new variant to our data type for expressions (varassign-exp (id symbol?) (rhs-exp expression?)) The semantics of “set x = x” will clarify the distinction between l-value and r-value. In main stream languages, the dereferencing is implicit, while in languages such as ML, it is explicit. E.g., in C, we can write the assignment “int x = 5; x = x;”, while in ML the corresponding code is “val x = ref 5; x = !x;” cs784(tk)

14 Ex1 Code in Our PL let x = 0 in letrec even () = if zero? (x) then 1 else let d = set x = sub1(x) in (odd) odd () = if zero? (x) then 0 in (even) in let d = set x = 13 in (odd) cs784(tk)

15 Ex2 Code in Our PL let g = let count = 0 in proc ()
let d = set count = add1(count) in count in +((g), (g)) Evaluates to 3 Evals to 3 cs784(tk)

16 Ex3 Code in Our PL let x = 100 in let p = proc (x)
let d = set x = add1(x) in x in +((p x),(p x)) Evals to 202 cs784(tk)

17 implement assignment (define-datatype reference reference? (a-ref (position integer?) (vec vector?))) cs784(tk)

18 Deref and setref! (define primitive-deref (lambda (ref) (cases reference ref (a-ref (pos vec) (vector-ref vec pos))))) (define primitive-setref! (lambda (ref val) (a-ref (pos vec) (vector-set! vec pos val))))) (define deref (primitive-deref ref))) (define setref! (lambda (ref val) (primitive-setref! ref val))) cs784(tk)

19 apply-env and apply-env-ref
(define apply-env (lambda (env sym) (deref (apply-env-ref env sym)))) (define apply-env-ref (cases environment env (empty-env-record () (eopl:error 'apply-env-ref "No binding for ~s" sym)) (extended-env-record (syms vals env) (let ((pos (rib-find-position sym syms))) (if (number? pos) (a-ref pos vals) (apply-env-ref env sym))))))) apply-env-ref returns the reference, not its value. cs784(tk)

20 varassign-exp (varassign-exp (id rhs-exp) (begin (setref! (apply-env-ref env id) (eval-expression rhs-exp env)) 1)) cs784(tk)

21 call-by-value v. -by-ref
Under call-by-value, a new reference is created for every evaluation of an operand Under call-by-reference, a new reference is created for every evaluation of an operand other than a variable. cs784(tk)

22 Call by-val v. -by-ref let a = 3 p = proc (x) set x = 4
in begin (p a); a end Call by val: 3 Call by ref: 4 cs784(tk)

23 call-by-reference example
let a = 3 b = 4 swap = proc (x, y) let temp = x in begin set x = y; set y = temp end (swap a b); -(a, b) By-ref, evals to +1. By-val, evals to -1. cs784(tk)

24 Implementation of call by-ref
define-datatype target direct targets expressed values corresponds to the behavior of call-by-value indirect targets references to expressed values corresponds to the behavior of call-by-ref no new location is created cs784(tk)

25 datatype target (define-datatype target target? (direct-target (expval expval?)) (indirect-target (ref ref-to-direct-target?))) (define expval? (lambda (x) (or (number? x) (procval? x)))) cs784(tk)

26 direct-target (define ref-to-direct-target? (lambda (x) (and (reference? x) (cases reference x (a-ref (pos vec) (cases target (vector-ref vec pos) (direct-target (v) #t) (indirect-target (v) #f))))))) cs784(tk)

27 deref (define deref (lambda (ref) (cases target (primitive-deref ref) (direct-target (expval) expval) (indirect-target (ref1) (cases target (primitive-deref ref1) (indirect-target (p) (eopl:error 'deref "Illegal reference: ~s" ref1))))))) cs784(tk)

28 setref! (define setref! (lambda (ref expval) (let ((ref (cases target (primitive-deref ref) (direct-target (expval1) ref) (indirect-target (ref1) ref1)))) (primitive-setref! ref (direct-target expval))))) cs784(tk)

29 Env built by call-by-reference
(proc (t, u, v, w) % p1 (proc (a, b) % p2 (proc (x, y, z) % p3 set y = 13 a b 6) 3 v) ) cs784(tk)

30 Lazy Evaluation Sometimes in a given call a procedure never refers to one or more of its formal parameters. A thunk is a procedure with no arguments. One can delay (perhaps indefinitely) the evaluation of an operand by encapsulating it as a thunk. Freezing: forming thunks Thawing: evaluating thunks cs784(tk)

31 call-by-name, -by-need
call-by-name: invoke the thunk every time the parameter is referred to. In the absence of side effects this is a waste of time, since the same value is returned each time. call-by-need: record the value of each thunk the first time it is invoked, and thereafter refers to the saved value. an example of memoization. In the absence of side-effects, call-by-name and call-by-need always give the same answer. In the presence of side-effects, however, it is easy to distinguish these two mechanisms. cs784(tk)

32 call-by-name and -need (part 1)
cs784(tk)

33 call-by-name and -need (part 2)
cs784(tk)

34 call-by-name and -need (part 3)
cs784(tk)

35 eval-rand for call-by-need
cs784(tk)

36 Example Blocks and Stmts
var x,y; {x = 3; y = 4; print (+ (x,y))} var x,y,z; {x = 3; y = 4; z = 0; while x do {z = + (z, y); x = sub1(x)}; print (z)} var x; {x = 3; print (x); var x; {x = 4; print (x)}; print (x)} var f, x; {f = proc (x, y) * (x, y); x = 3; print ((f 4 x))} cs784(tk)

37 Our Language cs784(tk)

38 execute-program (define execute-program (lambda (pgm) (cases program pgm (a-program (stmt) (execute-stmt stmt (init-env)))))) cs784(tk)

39 execute-stmt (define execute-stmt (lambda (stmt env) (cases stmt stmt (assign-stmt (id exp) …) (print-stmt (exp) … ) (compound-stmt (stmts) …) (if-stmt (exp true-stmt false- stmt) …) (while-stmt (exp stmt) …) (block-stmt (ids stmt) … )))) cs784(tk)

40 …, while-stmt, … (compound-stmt (stmts) (for-each (lambda (stmt)
(execute-st st env)) sts)) (while-stmt (exp stmt) (let loop () (if (true-value? (eval-expression exp env)) (begin (execute-stmt stmt env) (loop))))) (block-stmt (ids stmt) (execute-stmt stmt (extend-env ids ids env))) cs784(tk)


Download ppt "Assignments and Procs w/Params"

Similar presentations


Ads by Google