assignments and procs w/ params
Post on 23-Feb-2016
32 Views
Preview:
DESCRIPTION
TRANSCRIPT
Assignments and Procs w/Params
cs784(tk) 1
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 =
– new Point(); • Point q = p;
• call by reference• void f(Point p){…};
• f(q);
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)
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 5SchemeRefresher
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 6SchemeRefresher
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))))) 3628800
CS784 7SchemeRefresher
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.
1. (let* ([x 1]2. [y (+ x 1)])3. (list y x)) (2 1)
CS784 8SchemeRefresher
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.
1. (letrec ((a b) (b 34)(c (+ b 5))) 2. (list a b c)) (#<undefined> 34 39)
3. (letrec ([is-even? (lambda (n)4. (or (zero? n)5. (is-odd? (sub1 n))))]6. [is-odd? (lambda (n)7. (and (not (zero? n))8. (is-even? (sub1 n))))])9. (is-odd? 11)) #t
CS784 9SchemeRefresher
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 10SchemeRefresher
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 )
cs784(tk)
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) 12
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?))
cs784(tk)
14
Ex1 Code in Our PL
let x = 0in letrec
even () =if zero? (x) then 1else let d = set x = sub1(x)in (odd)odd () =if zero? (x) then 0else let d = set x = sub1(x)in (even)in let d = set x = 13 in (odd)
cs784(tk)
15
Ex2 Code in Our PL
let g =let count = 0in proc ()
let d = set count = add1(count)in count
in +((g), (g))• Evaluates to 3cs784(tk)
16
Ex3 Code in Our PL
let x = 100in let p = proc (x)
let d = set x = add1(x) in x
in +((p x),(p x))• Evals to 202
cs784(tk)
implement assignment
(define-datatype reference reference?(a-ref
(position integer?)(vec vector?)))
cs784(tk) 17
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) (cases reference ref
(a-ref (pos vec) (vector-set! vec pos val)))))
(define deref (lambda (ref) (primitive-deref ref)))
(define setref! (lambda (ref val) (primitive-setref! ref val)))
cs784(tk)
apply-env and apply-env-ref(define apply-env (lambda (env sym) (deref (apply-env-ref env sym))))
(define apply-env-ref (lambda (env sym) (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)))))))
cs784(tk) 19
varassign-exp
(varassign-exp (id rhs-exp)(begin
(setref! (apply-env-ref env id) (eval-expression rhs-exp env))1))
cs784(tk) 20
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) 21
Call by-val v. -by-ref
let a = 3p = proc (x) set x = 4
in begin (p a); a end
• Call by val: 3• Call by ref: 4
cs784(tk) 22
call-by-reference examplelet a = 3b = 4swap = proc (x, y)let temp = xin beginset x = y;set y = temp end
in begin(swap a b);-(a, b)
end
cs784(tk) 23
By-ref, evals to +1.By-val, evals to -1.
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) 24
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) 25
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) 26
deref(define deref (lambda (ref) (cases target (primitive-deref ref) (direct-target (expval) expval) (indirect-target (ref1) (cases target (primitive-deref ref1)(direct-target (expval) expval)(indirect-target (p) (eopl:error 'deref "Illegal reference: ~s" ref1)))))))
cs784(tk) 27
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) 28
Env built by call-by-reference
cs784(tk) 29
(proc (t, u, v, w) % p1 (proc (a, b) % p2 (proc (x, y, z) % p3 set y = 13 a b 6) 3 v)5 6 7 8)
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 thunkscs784(tk) 30
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.
cs784(tk) 31
call-by-name and -need (part 1)
cs784(tk) 32
call-by-name and -need (part 2)
cs784(tk) 33
call-by-name and -need (part 3)
cs784(tk) 34
eval-rand for call-by-need
cs784(tk) 35
Example Blocks and Stmtsvar 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) 36
Our Language
cs784(tk) 37
execute-program
(define execute-program (lambda (pgm) (cases program pgm (a-program (stmt)
(execute-stmt stmt (init-env))))))
cs784(tk) 38
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) 39
…, 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) 40
top related