Assignments and Procs w/Params

Slides:



Advertisements
Similar presentations
Cs784(Prasad)L10Rec1 Implementing Recursion. cs784(Prasad)L10Rec2 let insufficient for recursion ( (let((fact(lambda (n) (if (zero? n) 1 (* n (fact (-
Advertisements

1 Programming Languages (CS 550) Mini Language Interpreter Jeremy R. Johnson.
Type Checking, Inference, & Elaboration CS153: Compilers Greg Morrisett.
Semantic Analysis Chapter 6. Two Flavors  Static (done during compile time) –C –Ada  Dynamic (done during run time) –LISP –Smalltalk  Optimization.
CSCI 330: Programming Language Concepts Instructor: Pranava K. Jha Control Flow-II: Execution Order.
Scheme in Scheme. Why implement Scheme in Scheme  Implementing a language is a good way to learn more about programming languages  Interpreters are.
Assignments and Procs w/Params EOPL3 Chapter 4. Expressible vs. Denotable values Expressible Values –the language can express and compute these –represented.
1 Programming Languages (CS 550) Lecture Summary Functional Programming and Operational Semantics for Scheme Jeremy R. Johnson.
Functional Programming. Pure Functional Programming Computation is largely performed by applying functions to values. The value of an expression depends.
Lecture 16 Subroutine Calls and Parameter Passing Semantics Dragon: Sec. 7.5 Fischer: Sec Procedure declaration procedure p( a, b : integer, f :
CS 355 – PROGRAMMING LANGUAGES Dr. X. Apply-to-all A functional form that takes a single function as a parameter and yields a list of values obtained.
Cs784(TK)1 Semantics of Procedures and Scopes. Kinds of Scope Static or Lexical scope –determined by structure of program –Scheme, C++, Java, and many.
Denotational Semantics Syntax-directed approach, generalization of attribute grammars: –Define context-free abstract syntax –Specify syntactic categories.
Functional programming: LISP Originally developed for symbolic computing Main motivation: include recursion (see McCarthy biographical excerpt on web site).
Functional programming: LISP Originally developed for symbolic computing First interactive, interpreted language Dynamic typing: values have types, variables.
SchemeCOP Introduction to Scheme. SchemeCOP Scheme Meta-language for coding interpreters –“ clean ” semantics Scheme = LISP + ALGOL –simple.
Cs784(Prasad)L123Assg1 Assignments. cs784(Prasad)L123Assg2 l-value vs. r-value Pascal/Ada: x := x + 1 C/Java: x = x + 1 l-value = location, address, reference,
EOPL3: Section 3.3 PROC and App B: SLLGEN
Imperative Programming
Cs784(tk)1 Implementing Recursion. Recap: Goals Experimenting with PL design alternatives Scoping, parameter passing, arrays,... Runnable prototype of.
Cs7100(Prasad)L8Proc1 Procedures. cs7100(Prasad)L8Proc2 Primitive procedures  etc User-defined procedures –Naming a sequence of operations.
Semantics. Semantics is a precise definition of the meaning of a syntactically and type-wise correct program. Ideas of meaning: –Operational Semantics.
1 The Evaluator. 2 Compiler vs. Interpreter Command Processing Unit The Computer Program in Low Level Machine Language Program in High Level Language.
Plt /17/ Environment-Passing Interpreters Programming Language Essentials 2nd edition Chapter 3.8 Parameter-Passing Variations.
Basic Scheme February 8, 2007 Compound expressions Rules of evaluation Creating procedures by capturing common patterns.
1/33 Basic Scheme February 8, 2007 Compound expressions Rules of evaluation Creating procedures by capturing common patterns.
1 Programming Languages (CS 550) Lecture 4 Summary Functional Programming and Operational Semantics for Scheme Jeremy R. Johnson.
1 FP Foundations, Scheme In Text: Chapter Chapter 14: FP Foundations, Scheme Mathematical Functions Def: A mathematical function is a mapping of.
CS314 – Section 5 Recitation 9
(Thunking about Thunks)
Operational Semantics of Scheme
Functional Programming
Abstract Syntax cs7100 (Prasad) L7AST.
Principles of programming languages 12: Functional programming
Basic Scheme February 8, 2007 Compound expressions Rules of evaluation
Edited by Original material by Eric Grimson
6.001 SICP Variations on a Scheme
Introduction to Scheme
Interpreters Study Semantics of Programming Languages through interpreters (Executable Specifications) cs7100(Prasad) L8Interp.
September 4, 1997 Programming Languages (CS 550) Lecture 6 Summary Operational Semantics of Scheme using Substitution Jeremy R. Johnson TexPoint fonts.
Closures and Streams cs784(Prasad) L11Clos
Implementing Recursion
Env. Model Implementation
Original material by Eric Grimson
Nondeterministic Evaluation
2.3 Representation Strategies for Data Types
Semantics of PLs via Interpreters: Getting Started
Mini Language Interpreter Programming Languages (CS 550)
The Metacircular Evaluator
FP Foundations, Scheme In Text: Chapter 14.
Abstract Syntax Prabhaker Mateti 1.
Dynamic Scoping Lazy Evaluation
The Metacircular Evaluator
Procedures App B: SLLGEN 1.
3.7 Variable Assignment Recall instance variables in Python:
3.4 Local Binding Recall Scheme's let: > (let ((x 5)‏ (y 6))
The Metacircular Evaluator (Continued)
6.001 SICP Further Variations on a Scheme
Extending our interpreted language with Scheme’s set!
Streams, Delayed Evaluation and a Normal Order Interpreter
Abstract Syntax cs7100 (Prasad) L7AST.
3.6 Interpreter: Recursion
6.001 SICP Variations on a Scheme
Chapter 3: Environment-Passing Interpreters
Assignments cs7100(Prasad) L13Assg.
6.001 SICP Interpretation Parts of an interpreter
topics interpreters meta-linguistic abstraction eval and apply
Recursive Procedures and Scopes
Rehearsal: Lazy Evaluation Infinite Streams in our lazy evaluator
Lecture 25: The Metacircular Evaluator Eval Apply
Presentation transcript:

Assignments and Procs w/Params cs784(tk)

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)

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)

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

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

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 SchemeRefresher

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

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

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

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) ) = 1 but (letrec ( (x y) (y 1) ) x ) = error 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)

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)

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)

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)

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)

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

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)

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)

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

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)

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)

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)

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)

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)

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)

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)

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)

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) cs784(tk)

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)

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)

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

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

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

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

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)

Our Language cs784(tk)

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

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)

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