Tail Recursion: Factorial. Begin at the beginning. How does it execute? Tail recursion. Tail recursive factorial. Tail recursive factorial

Similar documents
Side note: Tail Recursion. Begin at the beginning. Side note: Tail Recursion. Base Types. Base Type: int. Base Type: int

Begin at the beginning

Programming Languages

Programming Languages

Variables and Bindings

Programming Languages

Recap. Recap. If-then-else expressions. If-then-else expressions. If-then-else expressions. If-then-else expressions

News. CSE 130: Programming Languages. Environments & Closures. Functions are first-class values. Recap: Functions as first-class values

Recap: Functions as first-class values

sum: tree -> int sum_leaf: tree -> int sum_leaf: tree -> int Representing Trees Next: Lets get cosy with Recursion Sum up the leaf values. E.g.

Programming Languages

OCaml. ML Flow. Complex types: Lists. Complex types: Lists. The PL for the discerning hacker. All elements must have same type.

Programming Languages

News. Programming Languages. Recap. Recap: Environments. Functions. of functions: Closures. CSE 130 : Fall Lecture 5: Functions and Datatypes

News. Programming Languages. Complex types: Lists. Recap: ML s Holy Trinity. CSE 130: Spring 2012

Plan (next 4 weeks) 1. Fast forward. 2. Rewind. 3. Slow motion. Rapid introduction to what s in OCaml. Go over the pieces individually

Programming Languages

Programming Languages

Programming Languages

OCaml. History, Variants. ML s holy trinity. Interacting with ML. Base type: Integers. Base type: Strings. *Notes from Sorin Lerner at UCSD*

Any questions. Say hello to OCaml. Say hello to OCaml. Why readability matters. History, Variants. Plan (next 4 weeks)

CMSC 330: Organization of Programming Languages. Functional Programming with Lists

So what does studying PL buy me?

Recap from last time. Programming Languages. CSE 130 : Fall Lecture 3: Data Types. Put it together: a filter function

CSE 341 Section 5. Winter 2018

CMSC 330: Organization of Programming Languages. Functional Programming with Lists

CVO103: Programming Languages. Lecture 5 Design and Implementation of PLs (1) Expressions

Function definitions. CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists. Example, extended. Some gotchas. Zach Tatlock Winter 2018

CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists. Zach Tatlock Winter 2018

Typical workflow. CSE341: Programming Languages. Lecture 17 Implementing Languages Including Closures. Reality more complicated

CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists. Dan Grossman Fall 2011

CSE 341: Programming Languages

Recap: ML s Holy Trinity

CSE 130 Programming Languages. Lecture 3: Datatypes. Ranjit Jhala UC San Diego

Recap: ML s Holy Trinity. Story So Far... CSE 130 Programming Languages. Datatypes. A function is a value! Next: functions, but remember.

CSE 130 Programming Languages. Datatypes. Ranjit Jhala UC San Diego

Product types add could take a single argument of the product type int * int fun add(,y):int = +y; > val add = fn : int * int -> int add(3,4); > val i

CSE 130 [Winter 2014] Programming Languages

A Second Look At ML. Chapter Seven Modern Programming Languages, 2nd ed. 1

Functional Programming. Pure Functional Programming

CSE 341, Autumn 2005, Assignment 3 ML - MiniML Interpreter

Programming Languages

SML A F unctional Functional Language Language Lecture 19

CPSC W1 University of British Columbia

Case study: leical analysis Leical analysis converts u sequences of characters u into u sequences of tokens u tokens are also called words or leemes F

Background. CMSC 330: Organization of Programming Languages. Useful Information on OCaml language. Dialects of ML. ML (Meta Language) Standard ML

Programming Languages and Compilers (CS 421)

FOFL and FOBS: First-Order Functions

Processadors de Llenguatge II. Functional Paradigm. Pratt A.7 Robert Harper s SML tutorial (Sec II)

Lambda Calculus. Concepts in Programming Languages Recitation 6:

CSE 413 Midterm, May 6, 2011 Sample Solution Page 1 of 8

Lists. Prof. Clarkson Fall Today s music: "Blank Space" by Taylor Swift

CMSC 330: Organization of Programming Languages. OCaml Imperative Programming

CSE341, Fall 2011, Midterm Examination October 31, 2011

A First Look at ML. Chapter Five Modern Programming Languages, 2nd ed. 1

CSE341, Fall 2011, Midterm Examination October 31, 2011

Lecture 11: Subprograms & their implementation. Subprograms. Parameters

A quick introduction to SML

Programming Language Concepts, cs2104 Lecture 04 ( )

Exercises on ML. Programming Languages. Chanseok Oh

CMSC 330: Organization of Programming Languages. Formal Semantics of a Prog. Lang. Specifying Syntax, Semantics

Lambda Calculus.

CMSC 330: Organization of Programming Languages. OCaml Imperative Programming

Tuples. CMSC 330: Organization of Programming Languages. Examples With Tuples. Another Example

Fall Lecture 3 September 4. Stephen Brookes

Programming Languages

Datatype declarations

CSE341: Programming Languages Lecture 6 Nested Patterns Exceptions Tail Recursion. Zach Tatlock Winter 2018

Programming Languages Lecture 14: Sum, Product, Recursive Types

CMSC 330: Organization of Programming Languages

CMSC 336: Type Systems for Programming Languages Lecture 4: Programming in the Lambda Calculus Acar & Ahmed 22 January 2008.

CSE341: Programming Languages Lecture 4 Records, Datatypes, Case Expressions. Dan Grossman Spring 2013

CMSC 330, Fall 2013, Practice Problem 3 Solutions

Type Checking. Outline. General properties of type systems. Types in programming languages. Notation for type rules.

All the operations used in the expression are over integers. a takes a pair as argument. (a pair is also a tuple, or more specifically, a 2-tuple)

Lecture #23: Conversion and Type Inference

Outline. General properties of type systems. Types in programming languages. Notation for type rules. Common type rules. Logical rules of inference

A Third Look At ML. Chapter Nine Modern Programming Languages, 2nd ed. 1

Scope, Functions, and Storage Management

Conversion vs. Subtyping. Lecture #23: Conversion and Type Inference. Integer Conversions. Conversions: Implicit vs. Explicit. Object x = "Hello";

The type checker will complain that the two branches have different types, one is string and the other is int

Note that pcall can be implemented using futures. That is, instead of. we can use

Introduction to OCaml

CMSC 330: Organization of Programming Languages. OCaml Expressions and Functions

CS109A ML Notes for the Week of 1/16/96. Using ML. ML can be used as an interactive language. We. shall use a version running under UNIX, called

Programs as data first-order functional language type checking

CSE341: Programming Languages Lecture 9 Function-Closure Idioms. Dan Grossman Winter 2013

A Brief Introduction to Standard ML

CS558 Programming Languages

Programming Languages. Next: Building datatypes. Suppose I wanted. Next: Building datatypes 10/4/2017. Review so far. Datatypes.

02157 Functional Programming. Michael R. Ha. Lecture 2: Functions, Types and Lists. Michael R. Hansen

CSE341 Autumn 2017, Midterm Examination October 30, 2017

# true;; - : bool = true. # false;; - : bool = false 9/10/ // = {s (5, "hi", 3.2), c 4, a 1, b 5} 9/10/2017 4

Programming Languages. Datatypes

Lecture #13: Type Inference and Unification. Typing In the Language ML. Type Inference. Doing Type Inference

Booleans (aka Truth Values) Programming Languages and Compilers (CS 421) Booleans and Short-Circuit Evaluation. Tuples as Values.

Program Flow. Instructions and Memory. Why are these 16 bits? C code. Memory. a = b + c. Machine Code. Memory. Assembly Code.

CSE341: Programming Languages Lecture 11 Type Inference. Dan Grossman Spring 2016

INF 212 ANALYSIS OF PROG. LANGS FUNCTION COMPOSITION. Instructors: Crista Lopes Copyright Instructors.

To figure this out we need a more precise understanding of how ML works

Transcription:

Begin at the beginning Epressions (Synta) Compile-time Static Eec-time Dynamic Types Values (Semantics) 1. Programmer enters epression 2. ML checks if epression is well-typed Using a precise set of rules, ML tries to find a unique type for the epression meaningful type for the epr 3. ML evaluates epression to compute value Of the same type found in step 2 Tail Recursion: Factorial let rec fact n = if n<=0 then 1 else n * fact (n-1);; 2 How does it eecute? let rec fact n = if n<=0 then 1 else n * fact (n-1);; fac 3;; Tail recursion Tail recursion: recursion where all recursive calls are immediately followed by a return in other words: not allowed to do anything between recursive call and return 3 4 Tail recursive factorial Tail recursive factorial let fact = let fact = let rec helper curr = if <= 0 then curr else helper ( - 1) ( * curr) in helper 1;; 5 6 1

How does it eecute? Tail recursion let fact = let rec helper curr = if <= 0 then curr else helper ( - 1) ( * curr) in helper 1;; Tail recursion: for each recursive call, the value of the recursive call is immediately returned in other words: not allowed to do anything between recursive call and return fact 3;; Why do we care about tail recursion? it turns out that tail recursion can be optimized into a simple loop 7 8 Compiler can optimize! Tail recursion summary let fact = let rec helper curr = if <= 0 fact() { curr := 1; while (1) { if ( <= 0) Tail recursive calls can be optimized as a jump then curr else helper ( - 1) ( * curr) in helper 1;; } then { return curr } else { := 1; curr := ( * curr) } Part of the language specification of some languages (ie: you can count on the compiler to optimize tail recursive calls) recursion! Loop! 9 10 Base Types Base Type: int Epressions built from sub-epressions Types computed from types of sub-epressions Values computed from values of sub-epressions 2

Base Type: int 2; 2 i i:int i ) i Base Type: float 2.0 2.0 e r:float r ) r 2+3; 5 e1 + e2 e 1 :int e 2 :int e 1 +e 2 :int e1+e2)v1+v2 2.0 +.3.0 5.0 e1 +. e2 e 1 :float e 1 :float e 1 +.e 2 :float e1+.e2)v1+.v2 7-4; 3 e1 - e2 e 1 :int e 2 :int e 1 -e 2 :int e1-e2)v1-v2 7.0. 4.0 3.0 e1 -. e2 e 1 :float e 2 :float e 1 -.e 2 :float e1-.e2)v1-.v2 (2+3)*(7-4); 15 e1 * e2 e 1 :int e 2 :int e 1 * e 2 :int e1*e2)v1*v2 (2.0 +. 3.0) /. (7.0 -. 4.0) 1.66.. e1 /. e2 e 1 :float e 2 :float e 1 /.e 2 :float e1/.e2)v1/.v2 Epressions built from sub-epressions Types computed from types of sub-epressions Values computed from values of sub-epressions Epressions built from sub-epressions Types computed from types of sub-epressions Values computed from values of sub-epressions Base Type: string ab ab s s:string s ) s Base Type: bool true true b b:bool b ) b 2 < 3 true e1 < e2 e 1 :int e 1 :int e 1 < e 2 :bool e1<e2 ) v1<v2 ab ^ cd abcd e1^e2 e 1 :string e 2 :string e 1^e 2 :string e1^e2)v1^v2 not(2<3) ( ab = cd ) false false not e e1 = e2 e : bool not e : bool e 1 :T e 2 :T e 1 =e 2 : bool e ) v not e ) not v e1=e2 ) v1=v2 Epressions built from sub-epressions Types computed from types of sub-epressions Values computed from values of sub-epressions not (2<3) && ( ab = cd ) false e1 && e2 e 1 :bool e 2 :bool e 1 &&e 2 :bool e1&&e2) v1 && v2 Base Type: bool Equality testing is built-in for all epr,values,types but compared epressions must have same type ecept for? function values why? ( ab = cd ) false e1 = e2 e 1 :T e 2 :T e 1 =e 2 : bool e1=e2 ) v1=v2 Type Errors pq ^ 9; (2 + a ); e 1 :string e 2 :string e 1^e 2 :string e 1 :int e 2 :int e 1 + e 2 : int Epressions built from sub-epressions Types computed from types of sub-epression If a sub-epression is not well-typed then whole epression is not well-typed 0 * (2 + a ); 3

Comple types: Tuples Comple types: Tuples (2+2, 7>8); (4,false) int * bool (2+2, 7>8); (4,false) int * bool e1:t1 e2:t2 (e 1,e 2 ) : T1 * T2 (e1,e2)) (v1,v2) Comple types: Tuples Can be of any fied size (9-3, ab ^ cd,7>8) (6, abcd, false) (int * string * bool) Comple types: Records {name= sarah ; age=31; pass=false} { name : string, age : int, pass : bool} Records are tuples with named elements e1:t1 e2:t2 en: Tn (e1,e2,,en) : T1 * T2* * Tn en ) vn (e1,e2,,en)) (v1,v2,,vn) {name= sarah ;age=31;pass=false}.age 31 int Elements can have different types Tuples can be nested in other tuples {age=31;name= sarah ;pass=false}.age {age=31;name= sarah ;pass=false}.pass 31 false int bool But wait Comple types: Lists All evaluation rules look like: e1 OP e2 ) v1 OP v2 [1+1;2+2;3+3;4+4] [2;4;6;8] int list [ a ; b ; c ^ d ]; [ a ; b ; cd ] string list [(1; a ^ b );(3+4, c )]; [(1, ab );(7, c )] (int*string) list [[1];[2;3];[4;5;6]]; [[1];[2;3];[4;5;6]]; (int list) list Unbounded size Can have lists of anything (e.g. lists of lists) 4

Comple types: Lists Comple types: Lists [] []: a list [] ) [] [e1;e2;e3; ] e1:t e2: T e3: T [e1;e2;e3; ] : T list e3)v3 [e1;e2; ] ) [v1;v2; ] All elements have the same type [1; pq ] Comple types: list..construct Comple types: list..construct Cons operator 1::[2;3] [1;2;3] int list e1:t e2: T list e1::e2 : T list e1)v1 e2 ) v2 e1::e2 ) v1::v2 1::[ b ; cd ]; Can only cons element to a list of same type Comple types: list construct Comple types: list deconstruct Append operator [1;2]@[3;4] [1;2;3;4] int list Reading the elements of a list: Two operators : hd (head) and tl (tail) e1:t list e2: T list e1@e2 : T list e1)v1 e2 ) v2 e1@e2 ) v1@v2 [1;2;3;4;5] hd [1;2;3;4;5] 1 int tl [1;2;3;4;5] [2;3;4;5] int list 1@[ b ; cd ]; [ a ; b ; cd ] hd [ a ; b ; cd ] a string tl [ a ; b ; cd ] [ b ; cd ] string list [1]@[ b ; cd ]; Can only append lists of the same type [(1, a );(7, c )] [[];[1;2;3];[4;5]] hd [(1, a );(7, c )](1, a ) Int * string hd [[];[1;2;3];4;5] 1 int list tl [(1, a );(7, c )] [(7; c )] (int * string) list tl [[];[1;2;3];4;5] [2;3;4;5] int list list 5

List: Heads and Tails List: Heads and Tails Head e :T list hd e : T e )v1::v2 hd e ) v1 Tail e :T list tl e : T list e ) v1::v2 tl e ) v2 (hd [[];[1;2;3]]) = (hd [[];[ a ]]) int list e 1 :T e 2 :T e 1 =e 2 : bool string list Recap Epressions (Synta) Compile-time Static Eec-time Dynamic Types Values (Semantics) Recap Integers: +,-,* floats: +,-,* Booleans: =,<, andalso, orelse, not Strings: ^ 1. Programmer enters epression 2. ML checks if epression is well-typed Using a precise set of rules, ML tries to find a unique type for the epression meaningful type for the epr 3. ML evaluates epression to compute value Of the same type found in step 2 Tuples, Records: #i Fied number of values, of different types Lists: ::,@,hd,tl,null Unbounded number of values, of same type If-then-else epressions if (1 < 2) then 5 else 10 5 if (1 < 2) then [ ab, cd ] else [ ] If-then-else is also an epression! Can use any epression in then, else branch if e1 then e2 else e3 int [ ab, cd ] string list If-then-else epressions if (1 < 2) then 5 else 10 5 if (1 < 2) then [ ab, cd ] else [ ] If-then-else is also an epression! Can use any epression in then, else branch if e1 then e2 else e3 int [ ab, cd ] string list e1 : bool e2: T e3: T if e1 then e2 else e3 : T e1 ) true e2 ) v2 if e1 then e2 else e3 ) v2 e1 ) false e3 ) v3 if e1 then e2 else e3 ) v3 6

If-then-else epressions if (1 < 2) then [1;2] else 5 if false then [1;2] else 5 then-subep, else-subep must have same type! which is the type of resulting epression e1 : bool e2: T e3: T if e1 then e2 else e3 : T If-then-else epressions e1 : bool e2: T e3: T if e1 then e2 else e3 : T Then-subep, Else-subep must have same type! Equals type of resulting epression if 1>2 then [1,2] else [] [] int list if 1<2 then [] else [ a ] [] string list (if 1>2 then [1,2] else [])=(if 1<2 then [] else [ a ]) Net: Variables Variables and Bindings Q: How to use variables in ML? Q: How to assign to a variable? # let = 2+2;; val : int = 4 let = e;; Bind the value of epression e to the variable Variables and Bindings # let = 2+2;; val : int = 4 # let y = * * ;; val y : int = 64 # let z = [;y;+y];; val z : int list = [4;64;68] Later declared epressions can use Most recent bound value used for evaluation Sounds like C/Java? NO! Environments ( Phone Book ) How ML deals with variables Variables = names Values = phone number y z 6 [4;64;68] : int list 8 : int 7

Environments and Evaluation ML begins in a top-level environment Some names bound let = e;; ML program = Sequence of variable bindings Program evaluated by evaluating bindings in order 1. Evaluate epr e in current env to get value v : t 2. Etend env to bind to v : t (Repeat with net binding) Environments Phone book Variables = names Values = phone number 1. Evaluate: Find and use most recent value of variable 2. Etend: Add new binding at end of phone book Eample Environments # let = 2+2;; val : int = 4 # let y = * * ;; val y : int = 64 # let z = [;y;+y];; val z : int list = [4;64;68] # let = + ;; val : int = 8 New binding! y y z y z 6 6 [4;64;68] : int list 6 [4;64;68] : int list 8 : int 1. Evaluate: Use most recent bound value of var 2. Etend: Add new binding at end How is this different from C/Java s store? # let = 2+2;; val : int = 4 # let f = fun y -> + y; val f : int -> int = fn # let = + ; val : int = 8 # f 0; val it : int = 4 f fn <code, >: int->int New binding: No change or mutation Old binding frozen in f Environments Environments 1. Evaluate: Use most recent bound value of var 2. Etend: Add new binding at end How is this different from C/Java s store? 1. Evaluate: Use most recent bound value of var 2. Etend: Add new binding at end How is this different from C/Java s store? # let = 2+2;; val : int = 4 # let = 2+2;; val : int = 4 # let f = fun y -> + y; val f : int -> int = fn # let = + ; val : int = 8 # f 0; val it : int = 4 f fn <code, >: int->int f fn <code, >: int->int 8 : int # let f = fun y -> + y; val f : int -> int = fn # let = + ; val : int = 8 # f 0; val it : int = 4 Binding used to eval (f ) f fn <code, >: int->int 8 : int Binding for subsequent 8

Cannot change the world Cannot assign to variables Can etend the env by adding a fresh binding Does not affect previous uses of variable Environment at fun declaration frozen inside fun value Frozen env used to evaluate application (f ) Q: Why is this a good thing? # let = 2+2;; val : int = 4 # let f = fun y -> + y;; val f : int -> int = fn # let = + ;; val : int = 8; # f 0;; val it : int = 4 Binding used to eval (f ) f fn <code, >: int->int 8 : int Binding for subsequent Cannot change the world Q: Why is this a good thing? A: Function behavior frozen at declaration Nothing entered afterwards affects function Same inputs always produce same outputs Localizes debugging Localizes reasoning about the program No sharing means no evil aliasing Eamples of no sharing Remember: No addresses, no sharing. Each variable is bound to a fresh instance of a value Tuples, Lists Efficient implementation without sharing? There is sharing and pointers but hidden from you Compiler s job is to optimize code Efficiently implement these no-sharing semantics Your job is to use the simplified semantics Write correct, cleaner, readable, etendable systems Recap: Environments Phone book Variables = names Values = phone number 1. Evaluate: Find and use most recent value of variable 2. Etend: let = e ;; Add new binding at end of phone book Net: Functions Functions Functions are values, can bind using let epr Epressions Values let fname = fun -> e ;; Types Problem: Can t define recursive functions! fname is bound after computing rhs value no (or old ) binding for occurences of fname inside e let rec fname = e ;; Occurences of fname inside e bound to this definition let rec fac = if <=1 then 1 else *fac (-1) 9

Functions Type Functions Type e1 : T2 -> T e1 e2 : T e2: T2 Functions Values Functions Values Two questions about function values: Two questions about function values: What is the value: What is the value: 1. of a function? 1. of a function? 2. of a function application (call)? (e1 e2) 2. of a function application (call)? (e1 e2) Values of functions: Closures Values of function application Body epression not evaluated until application but type-checking takes place at compile time i.e. when function is defined Function value = <code + environment at definition> closure # let = 2+2;; val : int = 4 # let f = fun y -> + y;; val f : int -> int = fn # let = + ;; val : int = 8 # f 0;; val it : int = 4 Binding used to eval (f ) f fn <code, >: int->int 8 : int Binding for subsequent Application: fancy word for call (e1 e2) apply the argument e2 to the (function) e1 Application Value: 1. Evaluate e1 in current env to get (function) v1 v1 is code + env code is (formal + body e), env is E 2. Evaluate e2 in current env to get (argument) v2 3. Evaluate body e in env E etended by binding to v2 10

Eample 1 let = 1;; let f y = + y;; let = 2;; let y = 3;; f ( + y);; Eample 1 let = 1;; let f y = + y;; let = 2;; let y = 3;; f ( + y);; Eample 2 let = 1;; let f y = let = 2 in fun z -> + y + z ;; let = 100;; let g = (f 4);; let y = 100;; (g 1);; Eample 2 let = 1;; let f y = let = 2 in fun z -> + y + z ;; let = 100;; let g = (f 4);; let y = 100;; (g 1);; Eample 3 let f g = let = 0 in g 2 ;; let = 100;; let h y = + y;; f h;; Static/Leical Scoping For each occurrence of a variable, Unique place in program tet where variable defined Most recent binding in environment Static/Leical: Determined from the program tet Without eecuting the programy Very useful for readability, debugging: Don t have to figure out where a variable got assigned Unique, statically known definition for each occurrence 11

Alternative: dynamic scoping let = 100 let f y = + y let g = f 0 let z = g 0 (* value of z? *) 12