1 / 40

Assignments and Procs w/ Params

Assignments and Procs w/ Params. 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)

cid
Download Presentation

Assignments and Procs w/ Params

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Assignments and Procs w/Params

  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)

  3. Sharing • sharing/aliasing • Point p = • new Point(); • Point q = p; • call by reference • void f(Point p){…}; • f(q);

  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

  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. SchemeRefresher

  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. SchemeRefresher

  7. Local Binding: let • (letproc-id ([idinit-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 SchemeRefresher

  8. Local Binding: let* • (let* ([idval-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 remainingval-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) SchemeRefresher

  9. Local Binding: letrec • (letrec ([idval-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> 34 39) • (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 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 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 )

  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

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

  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 else let d = set x = sub1(x) in (even) in let d = set x = 13 in (odd)

  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

  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

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

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

  19. 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 (symsvalsenv) (let ((pos (rib-find-position sym syms))) (if (number? pos) (a-ref pos vals) (apply-env-ref env sym)))))))

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

  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.

  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

  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 in begin (swap a b); -(a, b) end By-ref, evals to +1. By-val, evals to -1.

  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

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

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

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

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

  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) 5 6 7 8)

  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

  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, andthereafter refers to the saved value. • an example of memoization.

  32. call-by-name and -need (part 1)

  33. call-by-name and -need (part 2)

  34. call-by-name and -need (part 3)

  35. eval-rand for call-by-need

  36. Example Blocks and Stmts varx,y; {x = 3; y = 4; print (+ (x,y))} varx,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))}

  37. Our Language

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

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

  40. …, while-stmt, … • (compound-stmt (stmts) (for-each (lambda (stmt) (execute-ststenv)) 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 idsenv)))

More Related