CS 312 Spring 2004 Lecture 18 Environment Model. Substitution Model Represents computation as doing substitutions for bound variables at reduction of.

Slides:



Advertisements
Similar presentations
Modern Programming Languages, 2nd ed.
Advertisements

Type Checking, Inference, & Elaboration CS153: Compilers Greg Morrisett.
CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists Dan Grossman Winter 2013.
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.
Lambda Calculus and Lisp PZ03J. Lambda Calculus The lambda calculus is a model for functional programming like Turing machines are models for imperative.
CSE341: Programming Languages Lecture 8 Lexical Scope and Function Closures Dan Grossman Fall 2011.
Foundations of Programming Languages: Introduction to Lambda Calculus
ISBN Chapter 10 Implementing Subprograms.
Functional programming: LISP Originally developed for symbolic computing Main motivation: include recursion (see McCarthy biographical excerpt on web site).
The lambda calculus David Walker CS 441. the lambda calculus Originally, the lambda calculus was developed as a logic by Alonzo Church in 1932 –Church.
CS 312 Spring 2002 Lecture 16 The Environment Model.
CS 536 Spring Code Generation II Lecture 21.
Semantics of Calls and Returns
Functional programming: LISP Originally developed for symbolic computing First interactive, interpreted language Dynamic typing: values have types, variables.
Functional Programming Element of Functional Programming.
Cs7100(Prasad)L8Proc1 Procedures. cs7100(Prasad)L8Proc2 Primitive procedures  etc User-defined procedures –Naming a sequence of operations.
CSE S. Tanimoto Lambda Calculus 1 Lambda Calculus What is the simplest functional language that is still Turing complete? Where do functional languages.
10/16/2015IT 3271 All about binding n Variables are bound (dynamically) to values n values must be stored somewhere in the memory. Memory Locations for.
Formal Semantics Chapter Twenty-ThreeModern Programming Languages, 2nd ed.1.
A Second Look At ML 1. Outline Patterns Local variable definitions A sorting example 2.
CSE 230 The -Calculus. Background Developed in 1930’s by Alonzo Church Studied in logic and computer science Test bed for procedural and functional PLs.
Chapter SevenModern Programming Languages1 A Second Look At ML.
CSE 130 : Spring 2011 Programming Languages Ranjit Jhala UC San Diego Lecture 5: Functions and Closures.
CSE 130 : Winter 2009 Programming Languages Lecture 11: What’s in a Name ?
CMSC 330: Organization of Programming Languages Operational Semantics.
Procedure Definitions and Semantics Procedures support control abstraction in programming languages. In most programming languages, a procedure is defined.
CS314 – Section 5 Recitation 9
Run-Time Environments Chapter 7
Type Checking and Type Inference
CSE341: Programming Languages Lecture 7 First-Class Functions
ML: a quasi-functional language with strong typing
Implementing Subprograms
The Environment Model*
Env. Model Implementation
CSE341: Programming Languages Lecture 8 Lexical Scope and Function Closures Dan Grossman Winter 2013.
CSE341: Programming Languages Lecture 8 Lexical Scope and Function Closures Dan Grossman Spring 2013.
The Metacircular Evaluator
Objective caml Daniel Jackson MIT Lab for Computer Science 6898: Advanced Topics in Software Design March 18, 2002.
CSE341: Programming Languages Lecture 7 First-Class Functions
FP Foundations, Scheme In Text: Chapter 14.
CSE341: Programming Languages Lecture 12 Equivalence
The Metacircular Evaluator
CSE341: Programming Languages Lecture 8 Lexical Scope and Function Closures Dan Grossman Spring 2016.
CSE341: Programming Languages Lecture 7 First-Class Functions
CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists
CSE 341 Section 5 Winter 2018.
Procedures App B: SLLGEN 1.
What is a programming language?
CSE341: Programming Languages Lecture 8 Lexical Scope and Function Closures Dan Grossman Autumn 2018.
CSE341: Programming Languages Lecture 12 Equivalence
CSE341: Programming Languages Lecture 12 Equivalence
CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists
CSE341: Programming Languages Lecture 8 Lexical Scope and Function Closures Zach Tatlock Winter 2018.
Programming Languages and Compilers (CS 421) #3: Closures, evaluation of function applications, order of evaluation #4: Evaluation and Application.
CSE341: Programming Languages Lecture 7 First-Class Functions
CSE341: Programming Languages Lecture 7 First-Class Functions
CSE341: Programming Languages Lecture 12 Equivalence
CSE 341 Lecture 11 b closures; scoping rules
CSE341: Programming Languages Lecture 8 Lexical Scope and Function Closures Dan Grossman Autumn 2017.
CSE S. Tanimoto Lambda Calculus
Scope, Function Calls and Storage Management
CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists
CSE341: Programming Languages Lecture 7 First-Class Functions
CSE341: Programming Languages Lecture 12 Equivalence
CSE341: Programming Languages Lecture 7 First-Class Functions
CSE341: Programming Languages Lecture 8 Lexical Scope and Function Closures Dan Grossman Spring 2019.
CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists
Brett Wortzman Summer 2019 Slides originally created by Dan Grossman
CSE341: Programming Languages Lecture 7 First-Class Functions
CSE341: Programming Languages Lecture 12 Equivalence
Presentation transcript:

CS 312 Spring 2004 Lecture 18 Environment Model

Substitution Model Represents computation as doing substitutions for bound variables at reduction of let, application: let val x = v in e  e { v / x } (fn( x : t )=> e )( v )  e { v / x } let val x = fn z:’a=>z in x(x(x)) end  (fn z=>z)((fn z=>z)(fn z=>z))

Problems Not a realistic implementation! Substitution is too slow. (fn( x : t )=> e )( v )  e { v / x } Idea: use environment to record substitutions, do them only as needed (fn( x : t )=> e )( v )  e Could be many x’s in here x = v environment

Environment Model No substitution, realistic cost model Environment is a finite map from variables to values Example: let val x = 2 val y = “hello” val f = fn z:int=>x in f(x + size(y)) end x = 2 y = “hello” f = fn z:int=>x Evaluate: f(x + size(y)) in environment: ?

Variables To evaluate a variable, look it up in the environment. To look it up, we start with the last binding added to the environment and then work towards the TOP. Evaluating “x” in this environment yields 3: x = 3 a = 1 y = 4 x = 2 z = 3 TOP Blue boxes: bindings

Let expressions To evaluate let val x = e1 in e2 : 1.Evaluate e1 in the current environment 2.Extend the current environment with a binding that maps x to the value of e1 3.Evaluate e2 in the extended environment 4.Restore the old environment (i.e., remove the binding for x ) 5.Return the value of e2

Let Example let val x = (1,2) in #1 x end TOPcurrent env

let val x = (1,2) in #1 x end 1. Evaluating (1,2) yields a pointer to a tuple in memory. TOP 1 2 current env Let Example

let val x = (1,2) in #1 x end 1. Evaluating (1,2) yields a pointer to a tuple in memory. 2. Extend the environment with a binding for x. TOP 1 2 x= current env

Let Example let val x = (1,2) in #1 x end 1. Evaluating (1,2) yields a pointer to a tuple in memory. 2. Extend the environment with a binding for x. 3. Evaluate the body of the let in the new environment. x evaluates to a pointer to the tuple, so #1 x evaluates to the first component, namely 1. TOP 1 2 x= current env

Let Example let val x = (1,2) in #1 x end 1. Evaluating (1,2) yields a pointer to a tuple in memory. 2. Extend the environment with a binding for x. 3. Evaluate the body of the let in the new environment. x evaluates to a pointer to the tuple, so #1 x evaluates to the first component, namely Restore the old environment. TOP 1 2 x= current env

Let Example let val x = (1,2) in #1 x end TOP Evaluating (1,2) yields a pointer to a tuple in memory. 2. Extend the environment with a binding for x. x= 3. Evaluate the body of the let in the new environment. x evaluates to a pointer to the tuple, so #1 x evaluates to the first component, namely Restore the old environment. 5. Return the value we got: 1 current env

Pictorial Overview: Primitive values like integers, reals, unit, or nil evaluate to themselves. A tuple value, such as (1,2,3) evaluates to a pointer to a box in memory containing the values of the sub-expressions: 123

Multiple Declarations To evaluate: let val x = e1 val y = e2 val z = e3 in e4 end Do the same the same thing as you would for: let val x = e1 in let val y = e2 in let val z = e3 in e4 end end end

let val x = (3,4) val y = (x,x) in #1(#2 y) end let val x = (3,4) in let val y = (x,x) in #1(#2 y) end end TOP current env Evaluation of Example

let val x = (3,4) val y = (x,x) in #1(#2 y) end let val x = (3,4) in let val y = (x,x) in #1(#2 y) end end TOP current env 3 4 Evaluation of Example

let val x = (3,4) val y = (x,x) in #1(#2 y) end let val x = (3,4) in let val y = (x,x) in #1(#2 y) end end TOP current env 3 4 x = current env

Evaluation of Example let val x = (3,4) val y = (x,x) in #1(#2 y) end let val x = (3,4) in let val y = (x,x) in #1(#2 y) end end TOP 3 4 x = current env

y = Evaluation of Example let val x = (3,4) val y = (x,x) in #1(#2 y) end let val x = (3,4) in let val y = (x,x) in #1(#2 y) end end TOP 3 4 x = current env

y = Evaluation of Example let val x = (3,4) val y = (x,x) in #1(#2 y) end let val x = (3,4) in let val y = (x,x) in #1(#2 y) end end TOP 3 4 x = current env

y = Evaluation of Example let val x = (3,4) val y = (x,x) in #1(#2 y) end let val x = (3,4) in let val y = (x,x) in #1(#2 y) end end TOP 3 4 x = current env Result = 3

y = Evaluation of Example let val x = (3,4) val y = (x,x) in #1(#2 y) end let val x = (3,4) in let val y = (x,x) in #1(#2 y) end end TOP 3 4 x = current env Result is 3 Restore last env

y = Evaluation of Example let val x = (3,4) val y = (x,x) in #1(#2 y) end let val x = (3,4) in let val y = (x,x) in #1(#2 y) end end TOP 3 4 x = current env Result is 3 Restore original env

Refs To evaluate ref e, evaluate e to a value first, and then allocate a new ref cell, place the value in the ref cell, and return a pointer to the ref cell. For instance, ref (1,2,3) evaluates to: 123 ref cells = red boxes.

Ref Example let val x = ref 2 in val y = x in x:=1; !y end TOP current env 2

Ref Example let val x = ref 2 in val y = x in x:=1; !y end TOP 2 x = current env

Ref Example let val x = ref 2 in val y = x in x:=1; !y end TOP 2 x = current env

y = Ref Example let val x = ref 2 in val y = x in x:=1; !y end TOP 2 x = current env

y = Ref Example let val x = ref 2 in val y = x in x:=1; !y end TOP 1 x = current env

y = Ref Example let val x = ref 2 in val y = x in x:=1; !y end TOP 1 x = current env Result= 1

Functions let val x = 2 val f = fn z:int => x in let val x = “bye” in f(size(x)) end How do we make sure the environment has the (correct) binding for x? –We must keep track of the environment at the point where the function was evaluated. –Function evaluation: fn z:int => x, not f(size(x)) We create a closure –A pair of a function and its environment Static scope: ML, Java, Scheme, … Dynamic scope: Perl, Python, BASIC

Functions To evaluate a function (fn x => e) create a closure out of the function and the current environment and return a pointer to the closure. y = 4 x = 2 TOP current env

To evaluate a function (fn x => e) create a closure out of the function and the current environment and return a pointer to the closure. Creating closures y = 4 x = 2 TOP fn x => e current env Result I’ll draw closures using yellow.

Function Example let val x = 2 val f = fn z:int => x in let val x = “bye” in f(size(x)) end TOP current env fn z:int => x x = 2 current env

Function Example let val x = 2 val f = fn z:int => x in let val x = “bye” in f(size(x)) end TOP current env fn z:int => x x = 2 f=

Function Example let val x = 2 val f = fn z:int => x in let val x = “bye” in f(size(x)) end TOP current env fn z:int => x x = 2 f= x = “bye”

Function Example let val x = 2 val f = fn z:int => x in let val x = “bye” in f(size(x)) end TOP fn z:int => x x = 2 f= x = “bye” current env

Function Calls To evaluate e1(e2): 1.evaluate e1 -- you should get a pointer to a closure. 2.evaluate e2 to a value. 3.save the current environment -- we’ll come back to it after the function call. 4.extend the environment of the closure, mapping the formal argument to the actual argument. 5.evaluate the body of the function within the extended environment -- this gives us our result value. 6.restore the old environment (saved in step 3) 7.return the result.

Function Call Example let val x = 2 val f = fn z:int => x in let val x = “bye” in f(size(x)) end TOP fn z:int => x x = 2 f= x = “bye” 1. Evaluate e1, e2 current env

Function Call Example let val x = 2 val f = fn z:int => x in let val x = “bye” in f(size(x)) end TOP saved env fn z:int => x x = 2 f= x = “bye” current env 1. Evaluate e1, e2 2. Save environ.

Function Call Example let val x = 2 val f = fn z:int => x in let val x = “bye” in f(size(x)) end TOP saved env fn z:int => x x = 2 f= x = “bye” current env 1. Evaluate e1, e2 2. Save environ. 3. Extend env with actual z = 3

Function Call Example let val x = 2 val f = fn z:int => x in let val x = “bye” in f(size(x)) end TOP saved env fn z:int => x x = 2 f= x = “bye” current env 1. Evaluate e1, e2 2. Save environ. 3. Extend env with actual 4. Evaluate body (result= 2) z = 3

Function Call Example let val x = 2 val f = fn z:int => x in let val x = “bye” in f(size(x)) end TOP current env fn z:int => x x = 2 f= x = “bye” 1. Evaluate e1, e2 2. Save environ. 3. Extend env with actual 4. Evaluate body (result= 2) 5. Restore env. (result= 2)

let val x = ref (fn x:int => x) val f = fn n:int => if n <= 1 then 1 else n * (!x)(n-1) in x := f; f(3) end Creating a cycle current env TOP

let val x = ref (fn x => x) val f = fn n => if n <= 1 then 1 else n * (!x)(n-1) in x := f; f(3) end current env TOP fn x => x Creating a cycle

let val x = ref (fn x => x) val f = fn n => if n <= 1 then 1 else n * (!x)(n-1) in x := f; f(3) end current env TOP fn x => x Creating a cycle

let val x = ref (fn x => x) val f = fn n => if n <= 1 then 1 else n * (!x)(n-1) in x := f; f(3) end current env TOP fn x => x Creating a cycle x =

let val x = ref (fn x => x) val f = fn n => if n <= 1 then 1 else n * (!x)(n-1) in x := f; f(3) end current env TOP fn x => x Creating a cycle x = fn n => if n <= 1 then 1 else n * (!x)(n-1)

let val x = ref (fn x => x) val f = fn n => if n <= 1 then 1 else n * (!x)(n-1) in x := f; f(3) end current env TOP Creating a cycle x = fn n => if n <= 1 then 1 else n * (!x)(n-1) f = fn x => x

let val x = ref (fn x => x) val f = fn n => if n <= 1 then 1 else n * (!x)(n-1) in x := f; f(3) end current env TOP Creating a cycle x = fn n => if n <= 1 then 1 else n * (!x)(n-1) f = fn x => x

let val x = ref (fn x => x) val f = fn n => if n <= 1 then 1 else n * (!x)(n-1) in x := f; f(3) end current env TOP Creating a cycle x = fn n => if n <= 1 then 1 else n * (!x)(n-1) f =

let val x = ref (fn x => x) val f = fn n => if n <= 1 then 1 else n * (!x)(n-1) in x := f; f(3) end saved env TOP Creating a cycle x = fn n => if n <= 1 then 1 else n * (!x)(n-1) f = n = 3 current env Note: !x is the same as f

let val x = ref (fn x => x) val f = fn n => if n <= 1 then 1 else n * (!x)(n-1) in x := f; f(3) end saved env 1 TOP Creating a cycle x = fn n => if n <= 1 then 1 else n * (!x)(n-1) f = n = 3 saved env 2 n = 2 curr env

let val x = ref (fn x => x) val f = fn n => if n <= 1 then 1 else n * (!x)(n-1) in x := f; f(3) end saved env 1 TOP Creating a cycle x = fn n => if n <= 1 then 1 else n * (!x)(n-1) f = n = 3 saved env 2 n = 2 saved 3 n = 1 curr env Result = 1

let val x = ref (fn x => x) val f = fn n => if n <= 1 then 1 else n * (!x)(n-1) in x := f; f(3) end saved env 1 TOP Creating a cycle x= fn n => if n <= 1 then 1 else n * (!x)(n-1) f = n= 3 saved env 2 n= 2 curr env n= 1 Result = 2*1

let val x = ref (fn x => x) val f = fn n => if n <= 1 then 1 else n * (!x)(n-1) in x := f; f(3) end saved env 1 TOP Creating a cycle x= fn n => if n <= 1 then 1 else n * (!x)(n-1) f= n= 3 curr env n= 2 n= 1 Result = 3*2*1

let val x = ref (fn x => x) val f = fn n => if n <= 1 then 1 else n * (!x)(n-1) in x := f; f(3) end curr env TOP Creating a cycle x= fn n => if n <= 1 then 1 else n * (!x)(n-1) f= n=3 n=2 n=1 f(3) = 6

Recursion let fun f(n) = if n <= 1 then 1 else n * f(n-1) in f(3) end 1.create a new binding for f before creating the closure and extend the current environment with it (but don’t put in the value yet.) 2. now create a closure for f that uses the extended environment. 3.fix the binding to use the closure!

Recursion let fun f(n) => if n <= 1 then 1 else n * f(n-1) in f(3) end current env TOP f= No value for f yet! 1.create a new binding for f before creating the closure and extend the current environment with it (but don’t put in the value yet.) 2. now create a closure for f that uses the extended environment. 3.fix the binding to use the closure!

1.create a new binding for f before creating the closure and extend the current environment with it (but don’t put in the value yet.) 2. now create a closure for f that uses the extended environment. 3.fix the binding to use the closure! Recursion current env TOP f= fn n => if n <= 1 then 1 else n * f(n-1) let fun f(n) => if n <= 1 then 1 else n * f(n-1) in f(3) end

Recursion current env TOP f= fn n => if n <= 1 then 1 else n * f(n-1) 1.create a new binding for f before creating the closure and extend the current environment with it (but don’t put in the value yet.) 2. now create a closure for f that uses the extended environment. 3.fix the binding to use the closure! let fun f(n) => if n <= 1 then 1 else n * f(n-1) in f(3) end

Cycle current env TOP f= fn n => if n <= 1 then 1 else n * f(n-1) let fun f(n) => if n <= 1 then 1 else n * f(n-1) in f(3) end Closure points to environment Environment points to closure 1.create a new binding for f before creating the closure and extend the current environment with it (but don’t put in the value yet.) 2. now create a closure for f that uses the extended environment. 3.fix the binding to use the closure!

Cycle current env TOP f= fn n => if n <= 1 then 1 else n * f(n-1) let fun f(n) => if n <= 1 then 1 else n * f(n-1) in f(3) end Closure points to environment Environment points to closure n=3 1.create a new binding for f before creating the closure and extend the current environment with it (but don’t put in the value yet.) 2. now create a closure for f that uses the extended environment. 3.fix the binding to use the closure!

Comparison current env TOP f= fn n => if n <= 1 then 1 else n * f(n-1) x= current env TOP fn n => if n <= 1 then 1 else n * (!x)(n-1) f=