PS4 #6: if you got points off because you didn’t do an intersect with accessible and the start states, submit a re- grade. Today: let, let*, letrec in.

Slides:



Advertisements
Similar presentations
(define (f x) (if (< x 0) (lambda (y) (- y x)) (lambda (y) (- x y)))) GE f: P1 para:x body:(if … )
Advertisements

Assignments and Procs w/Params EOPL3 Chapter 4. Expressible vs. Denotable values Expressible Values –the language can express and compute these –represented.
Recap 1.Programmer enters expression 2.ML checks if expression is “well-typed” Using a precise set of rules, ML tries to find a unique type for the expression.
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.
1 The metacircular evaluator Names Extend the calculator to store intermediate results as named values (define x (+ 4 5)) store result as x (+ x.
Defining New Special Forms (unless test body) (if (not test) body #f) (when (not test) body)
Imperative Programming: Mutable data (local state, letrec, set!) Example 1: counter (define counter (let ((count 0)) (lambda () (set! count (+ count 1))
Imperative Programming Chapter 6 1. Local State Real world software like: Banks Course grading system Are state systems. i.e. they change along time:
1 Functional programming Languages And a brief introduction to Lisp and Scheme.
(define applicative-eval (lambda (exp) (cond ((atomic? exp) (eval-atomic exp)) ((special-form? exp) (eval-special-form exp)) ((list-form? exp) (eval-list.
1 Scheme Scheme is a functional language. Scheme is based on lambda calculus. lambda abstraction = function definition In Scheme, a function is defined.
6.001 SICP SICP – October environment Trevor Darrell 32-D512 Office Hour: W web page:
CS 312 Spring 2004 Lecture 18 Environment Model. Substitution Model Represents computation as doing substitutions for bound variables at reduction of.
מבוא מורחב למדעי המחשב בשפת Scheme תרגול 11. Dotted tail notation (define (proc m1 m2. opt) ) Mandatory Arguments: m1, m2 Mandatory Arguments: m1, m2.
Functional programming: LISP Originally developed for symbolic computing Main motivation: include recursion (see McCarthy biographical excerpt on web site).
CS 312 Spring 2002 Lecture 16 The Environment Model.
6.001 SICP SICP – Evaluation I Recitation 11/19/2004 Eval review Evaluation examples define lambda apply New language elements.
1 Scheme Although Scheme is syntactically a simple language, it supports sophisticated modeling: higher-order functions are a powerful tool in describing.
1 Functional languages (e.g. Scheme, ML) Scheme is a functional language. Scheme is based on lambda calculus. lambda abstraction = function definition.
Functional programming: LISP Originally developed for symbolic computing First interactive, interpreted language Dynamic typing: values have types, variables.
Fall 2008Programming Development Techniques 1 Topic 18 Environment Model of Evaluation Section 3.2 Acknowledgement: This lecture (and also much of the.
PPL Syntax & Formal Semantics Lecture Notes: Chapter 2.
PPL Syntax & Formal Semantics Lecture Notes: Chapter 2.
The environment model evaluator and compiler 1 The env model evaluator Motivation In one word: Efficiency Saves repeated renaming and substitution: Using.
Cs1120 Fall 2009 David Evans Lecture 20: Programming with State.
Scheme in Scheme 1. Why implement Scheme in Scheme  Implementing a language is a good way to learn more about programming languages  Interpreters are.
Cs7100(Prasad)L8Proc1 Procedures. cs7100(Prasad)L8Proc2 Primitive procedures  etc User-defined procedures –Naming a sequence of operations.
David Evans CS200: Computer Science University of Virginia Computer Science Lecture 18: Think Globally, Mutate Locally.
Scheme in Scheme. Why implement Scheme in Scheme  Implementing a language is a good way to learn more about programming languages  Interpreters are.
Principles of Programming Languages Lecture 1 Slides by Yaron Gonen, based on slides by Daniel Deutch and lecture notes by Prof. Mira Balaban.
David Evans CS200: Computer Science University of Virginia Computer Science Lecture 19: Environments.
Imperative Programming Chapter 6 1. Local State Real world software like: Banks Course grading system Are state systems. i.e. they change along time:
1 Env. Model Implementation & Analyzer Practice Session #10 Env. Model Implementation & Analyzer Practice Session #10.
Fall 2008Programming Development Techniques 1 Topic 17 Assignment, Local State, and the Environment Model of Evaluation Section 3.1 & 3.2.
The Environment Model an extension of the substitution model more "operational" fully explains static scoping and the process by which variable names are.
Message Passing: Alternative to Generics data is “active” — knows how to compute dispatch on operation (define (rat (n ) (d )) (method ((op )) (cond ((=
1 Introduction to Functional Programming in Racket CS 270 Math Foundations of CS Jeremy Johnson.
CS314 – Section 5 Recitation 9
Operational Semantics of Scheme
Environments and the Contour Model
The interpreter.
The Environment Model*
September 4, 1997 Programming Languages (CS 550) Lecture 6 Summary Operational Semantics of Scheme using Substitution Jeremy R. Johnson TexPoint fonts.
COP4020 Programming Languages
Implementing Recursion
Env. Model Implementation
SSA in Scheme Static single assignment (SSA) :
First-class continuations
The Metacircular Evaluator
Dynamic Scoping Lazy Evaluation
And more store-passing interpreters
What is a programming language?
3.4 Local Binding Recall Scheme's let: > (let ((x 5)‏ (y 6))
Announcements Quiz 6 HW7 due Tuesday, October 30
Lecture 26: The Metacircular Evaluator Eval Apply
Explicit Application of Procedures, and Explicit Evaluation
Mutable Data (define mylist (list 1 2 3)) (bind ((new (list 4)))
Streams, Delayed Evaluation and a Normal Order Interpreter
3.6 Interpreter: Recursion
6.001 SICP Variations on a Scheme
Programming Languages and Compilers (CS 421) #3: Closures, evaluation of function applications, order of evaluation #4: Evaluation and Application.
Chapter 3: Environment-Passing Interpreters
Combining Like Terms TeacherTwins©2014.
6.001 SICP Interpretation Parts of an interpreter
Assignments and Procs w/Params
topics interpreters meta-linguistic abstraction eval and apply
Rules of evaluation The value of a number is itself.
More Scheme CS 331.
Lecture 25: The Metacircular Evaluator Eval Apply
Presentation transcript:

PS4 #6: if you got points off because you didn’t do an intersect with accessible and the start states, submit a re- grade. Today: let, let*, letrec in the env. model side-effecting lists (set-car!, set-cdr!) Tomorrow: more on side-effecting data structures (e.g., chains)

To evaluate a lambda in environment E, build a closure. To evaluate a (non-special form) combination: (f a1... an) in E: evaluate f in E and get a closure c evaluate each argument ai in E to get a value vi apply the closure c to the values v1... vn To apply a closure c to values v1... vn: build a new frame, binding closure formal parameters to actual parameters v1... vn link the frame into the environment of the closure to yield a new environment evaluate the body of the closure in the new environment

To evaluate: (let ((x1 e1) (x2 e2)... (xn en)) e) in environment E: 1. evaluate e1, e2,..., en in environment E producing values v1, v2,..., vn. 2. build a new frame that binds x1 to v1, x2 to v2,..., xn to vn. 3. link the new frame into E to yield a new environment. 4. evaluate the body of the let, e, in the new environment.

(let ((x 1) (y 2)) (* x y)) *: {mult} 1. evaluate 1 and 2 in the current env.

(let ((x 1) (y 2)) (* x y)) *: {mult} x: 1 y: 2 2. build new frame with bindings 3. link it in to the env.

(let ((x 1) (y 2)) (* x y)) *: {mult} x: 1 y: 2 4. evaluate body of let in new env.

(let ((x 3) (y (* x x))) (* x y)) *: {mult} 1. evaluate 1 in environment to get 1...

(let ((x 3) (y (* x x))) (* x y)) *: {mult}...but evaluating (* x x) fails! (no binding for x in the environment!)

Alternative: (let ((x1 e1) (x2 e2)... (xn en)) e) in environment E, evaluate: ((lambda (x1 x2... xn) e) e1 e2... en)

(let ((x 1) (y 2)) => ((lambda (x y) (* x y)) 1 2) (* x y)) *: {mult}

(let ((x 1) (y 2)) => ((lambda (x y) (* x y)) 1 2) (* x y)) *: {mult}

(let ((x 1) (y 2)) => ((lambda (x y) (* x y)) 1 2) (* x y)) args: (x y) body: (* x y) env : *: {mult}

(let ((x 1) (y 2)) => ((lambda (x y) (* x y)) 1 2) (* x y)) args: (x y) body: (* x y) env : *: {mult} Now apply the closure to 1 and 2...

(let ((x 1) (y 2)) => ((lambda (x y) (* x y)) 1 2) (* x y)) args: (x y) body: (* x y) env : *: {mult} x: 1 y: 2...and we get 2.

(let ((x 1) (y 2)) => ((lambda (x y) (* x y)) 1 2) (* x y)) args: (x y) body: (* x y) env : *: {mult} x: 1 y: 2 afterwards, we continue evaluating in the top-level environment...

(let ((x 1) (y 2)) => ((lambda (x y) (* x y)) 1 2) (* x y)) args: (x y) body: (* x y) env : *: {mult} x: 1 y: 2 and the intermediate closure and frame are garbage collected

To evaluate: (let* ((x1 e1) (x2 e2)... (xn en)) e) in environment E: 1. evaluate e1 in E to v1 2. add a new frame mapping x1 to v1, yielding E2 3. evaluate e2 in E2 to v2 4. add a new frame mapping x2 to v2, yielding E3... 2n-1. evaluate en in En to vn 2n. add a new frame mapping xn to vn, yielding E’ 2n+1. evaluate the body e in E’

(let* ((x 3) (y (* x x))) (* x y)) *: {mult}

(let* ((x 3) (y (* x x))) (* x y)) *: {mult} x:3

(let* ((x 3) (y (* x x))) (* x y)) *: {mult} x:3 The (* x x) yields 9...

(let* ((x 3) (y (* x x))) (* x y)) *: {mult} x:3 y:9

(let* ((x 3) (y (* x x))) (* x y)) *: {mult} x:3 y:9 The (* x y) yields 3*9 = 27

Alternative: (let* ((x1 e1) (x2 e2)... (xn en)) e) in environment E, evaluate: (let ((x1 e1)) (((...(lambda (x1) (let ((x2 e2)) ((lambda (x2)... =>... (let ((xn en)) ((lambda (xn) e)...)) e))) e1) e2)... en)

(let* ((x 3) (let ((x 3)) (y (* x x))) => (let ((y (* x x)) => (* x y)) (* x y))) ((lambda (x) ((lambda (y) (* x y)) (* x x))) 3) *: {mult}

(let* ((x 3) (let ((x 3)) (y (* x x))) => (let ((y (* x x)) => (* x y)) (* x y))) ((lambda (x) ((lambda (y) (* x y)) (* x x))) 3) *: {mult} args: x body: env:

(let* ((x 3) (let ((x 3)) (y (* x x))) => (let ((y (* x x)) => (* x y)) (* x y))) ((lambda (x) ((lambda (y) (* x y)) (* x x))) 3) *: {mult} args: x body: env: x:3

(let* ((x 3) (let ((x 3)) (y (* x x))) => (let ((y (* x x)) => (* x y)) (* x y))) ((lambda (x) ((lambda (y) (* x y)) (* x x))) 3) *: {mult} args: x body: env: x:3

(let* ((x 3) (let ((x 3)) (y (* x x))) => (let ((y (* x x)) => (* x y)) (* x y))) ((lambda (x) ((lambda (y) (* x y)) (* x x))) 3) *: {mult} x:3

(let* ((x 3) (let ((x 3)) (y (* x x))) => (let ((y (* x x)) => (* x y)) (* x y))) ((lambda (x) ((lambda (y) (* x y)) (* x x))) 3) *: {mult} x:3 args: y body: (* x y) env:

(let* ((x 3) (let ((x 3)) (y (* x x))) => (let ((y (* x x)) => (* x y)) (* x y))) ((lambda (x) ((lambda (y) (* x y)) (* x x))) 3) *: {mult} x:3 args: y body: (* x y) env: And then we apply the closure to 9...

(let* ((x 3) (let ((x 3)) (y (* x x))) => (let ((y (* x x)) => (* x y)) (* x y))) ((lambda (x) ((lambda (y) (* x y)) (* x x))) 3) *: {mult} x:3 args: y body: (* x y) env: y:9...and as before get 27 as the result.

To evaluate: (letrec ((x1 e1) (x2 e2)... (xn en)) e) in environment E: 1. build a new frame mapping each xi to *void* looking up *void* should be an error link the frame into E yielding a new environment E’ 3. evaluate each ei in the new environment E’ to a value vi 4. set! the bindings in the frame so that xi maps to vi 5. evaluate the body e in E’

(letrec ((f (lambda (x) (if (= 1 x) 1 (* x (f (- 1 x))))))) (f 3)) *: {mult} +: {add} =: {equal} -: {sub} 1. create a new frame mapping f to *void*

(letrec ((f (lambda (x) (if (= 1 x) 1 (* x (f (- 1 x))))))) (f 3)) *: {mult} +: {add} =: {equal} -: {sub} 1. create a new frame mapping f to *void* 2. link it in to the environment f: *void*

(letrec ((f (lambda (x) (if (= 1 x) 1 (* x (f (- 1 x))))))) (f 3)) *: {mult} +: {add} =: {equal} -: {sub} 3. evaluate the expression in the new environment to get a value v. f: *void*

(letrec ((f (lambda (x) (if (= 1 x) 1 (* x (f (- 1 x))))))) (f 3)) *: {mult} +: {add} =: {equal} -: {sub} 3. evaluate the expression in the new environment to get a value v. f: *void* args: x body: (if (= 1 x) 1 (* x (f (- 1 x)))) env :

(letrec ((f (lambda (x) (if (= 1 x) 1 (* x (f (- 1 x))))))) (f 3)) *: {mult} +: {add} =: {equal} -: {sub} 4. set! the binding in the frame so that f maps to v f: args: x body: (if (= 1 x) 1 (* x (f (- 1 x)))) env :

(letrec ((f (lambda (x) (if (= 1 x) 1 (* x (f (- 1 x))))))) (f 3)) *: {mult} +: {add} =: {equal} -: {sub} 5. now evaluate the body of the letrec in the new environment. f: args: x body: (if (= 1 x) 1 (* x (f (- 1 x)))) env :

(letrec ((f (lambda (x) (if (= 1 x) 1 (* x (f (- 1 x))))))) (f 3)) *: {mult} +: {add} =: {equal} -: {sub} f: args: x body: (if (= 1 x) 1 (* x (f (- 1 x)))) env : x: 3

(if (= 1 x) 1 (* x (f (- 1 x)))) => (if (= 1 3) 1 (* x (f (- 1 x)))) => (if #f 1 (* x (f (- 1 x)))) => (* x (f (- 1 x))) => (* 3 (f (- 1 x))) => (* 3 (f 2)) *: {mult} +: {add} =: {equal} -: {sub} f: args: x body: (if (= 1 x) 1 (* x (f (- 1 x)))) env : x: 3

(if (= 1 x) 1 (* x (f (- 1 x)))) => (if (= 1 2) 1 (* x (f (- 1 x)))) => (if #f 1 (* x (f (- 1 x)))) => (* x (f (- 1 x))) => (* 2 (f (- 1 x))) => (* 2 (f 1)) *: {mult} +: {add} =: {equal} -: {sub} f: args: x body: (if (= 1 x) 1 (* x (f (- 1 x)))) env : x: 3 x: 2

(if (= 1 x) 1 (* x (f (- 1 x)))) => (if (= 1 1) 1 (* x (f (- 1 x)))) => (if #t 1 (* x (f (- 1 x)))) => 1 *: {mult} +: {add} =: {equal} -: {sub} f: args: x body: (if (= 1 x) 1 (* x (f (- 1 x)))) env : x: 3 x: 2 x: 1

(if (= 1 x) 1 (* x (f (- 1 x)))) => (* 2 (f 1)) => (* 2 1) => 2 *: {mult} +: {add} =: {equal} -: {sub} f: args: x body: (if (= 1 x) 1 (* x (f (- 1 x)))) env : x: 3 x: 2

(if (= 1 x) 1 (* x (f (- 1 x)))) => (* 3 (f 2)) => (* 3 2) => 6 *: {mult} +: {add} =: {equal} -: {sub} f: args: x body: (if (= 1 x) 1 (* x (f (- 1 x)))) env : x: 3

(letrec ((f (lambda (x) (g x))) (g (lambda (y) (f y)))) (f 0))

(letrec ((f (lambda (x) (g x))) (g (lambda (y) (f y)))) (f 0)) f: *void* g: *void*

(letrec ((f (lambda (x) (g x))) (g (lambda (y) (f y)))) (f 0)) f: *void* g: *void*

(letrec ((f (lambda (x) (g x))) (g (lambda (y) (f y)))) (f 0)) f: *void* g: *void* args: x body: (g x) env :

(letrec ((f (lambda (x) (g x))) (g (lambda (y) (f y)))) (f 0)) f: *void* g: *void* args: x body: (g x) env :

args: y body: (f y) env : (letrec ((f (lambda (x) (g x))) (g (lambda (y) (f y)))) (f 0)) f: *void* g: *void* args: x body: (g x) env :

(letrec ((f (lambda (x) (g x))) (g (lambda (y) (f y)))) (f 0)) f: g: args: x body: (g x) env : args: y body: (f y) env :

(letrec ((f (lambda (x) (g x))) (g (lambda (y) (f y)))) (f 0)) f: g: args: x body: (g x) env : args: y body: (f y) env :

(letrec ((f (lambda (x) (g x))) (g (lambda (y) (f y)))) (f 0)) f: g: args: x body: (g x) env : args: y body: (f y) env : x: 0

(letrec ((f (lambda (x) (g x))) (g (lambda (y) (f y)))) (f 0)) f: g: args: x body: (g x) env : args: y body: (f y) env : x: 0 y: 0

Alternative: to evaluate (letrec ((x1 e1)... (xn en)) e) in environment E, evaluate? (let ((x1 ‘void) ; define place-holders... (xn ‘void)) (let ((v1 e1) ; evaluate e1,...,en... ; and save values as v1,...,vn (vn en)) (set! x1 v1) ; set x1,...,xn to v1,...,vn... (set! xn vn) e))

(letrec ((f (lambda (x) (g x))) (g (lambda (y) (f y)))) (f 0)) => (let ((f ‘void) (g ‘void)) (let ((v1 (lambda (x) (g x))) (v2 (lambda (y) (f y)))) (set! f v1) (set! g v2) (f 0)))

(let ((f ‘void) (g ‘void)) (let ((v1 (lambda (x) (g x))) (v2 (lambda (y) (f y)))) (set! f v1) (set! g v2) (f 0))) f: ‘void g: ‘void

f: ‘void g: ‘void args: x body: (g x) env : (let ((f ‘void) (g ‘void)) (let ((v1 (lambda (x) (g x))) (v2 (lambda (y) (f y)))) (set! f v1) (set! g v2) (f 0)))

f: ‘void g: ‘void args: x body: (g x) env : args: y body: (f y) env : (let ((f ‘void) (g ‘void)) (let ((v1 (lambda (x) (g x))) (v2 (lambda (y) (f y)))) (set! f v1) (set! g v2) (f 0)))

f: ‘void g: ‘void args: x body: (g x) env : args: y body: (f y) env : v1: v2: (let ((f ‘void) (g ‘void)) (let ((v1 (lambda (x) (g x))) (v2 (lambda (y) (f y)))) (set! f v1) (set! g v2) (f 0)))

f: g: ‘void args: x body: (g x) env : args: y body: (f y) env : v1: v2: (let ((f ‘void) (g ‘void)) (let ((v1 (lambda (x) (g x))) (v2 (lambda (y) (f y)))) (set! f v1) (set! g v2) (f 0)))

f: g: args: x body: (g x) env : args: y body: (f y) env : v1: v2: (let ((f ‘void) (g ‘void)) (let ((v1 (lambda (x) (g x))) (v2 (lambda (y) (f y)))) (set! f v1) (set! g v2) (f 0)))

f: g: args: x body: (g x) env : args: y body: (f y) env : v1: v2: (let ((f ‘void) (g ‘void)) (let ((v1 (lambda (x) (g x))) (v2 (lambda (y) (f y)))) (set! f v1) (set! g v2) (f 0)))

Mutable Data (define mylist (list 1 2 3)) (let ((new (list 4))) (set! (tail new) (tail mylist)) (set! (tail mylist) new)) () mylist

4 () new Mutable Data (define mylist (list 1 2 3)) (let ((new (list 4))) (set! (tail new) (tail mylist)) (set! (tail mylist) new)) mylist ()

new Mutable Data (define mylist (list 1 2 3)) (let ((new (list 4))) (set! (tail new) (tail mylist)) (set! (tail mylist) new)) mylist ()

new Mutable Data (define mylist (list 1 2 3)) (let ((new (list 4))) (set! (tail new) (tail mylist)) (set! (tail mylist) new)) mylist () X

Mutable Data (define mylist (list 1 2 3)) (let ((new (list 4))) (set! (tail new) (tail mylist)) (set! (tail mylist) new)) new mylist ()