A Functional Space Model. COS 326 David Walker Princeton University

Size: px
Start display at page:

Download "A Functional Space Model. COS 326 David Walker Princeton University"

Transcription

1 A Functional Space Model COS 326 David Walker Princeton University

2 Data type representations: Last Time type tree = Leaf Node of int * tree * tree Leaf: Node(i, left, right): 0 Node 3 left right

3 This Time Understanding the space complexity of functional programs At least two interesting components: the amount of live space at any instant in time the rate of allocation a function call may not change the amount of live space by much but may allocate at a substantial rate because functional programs act by generating new data structures and discarding old ones, they often allocate at a great rate» OCaml garbage collector is optimized with this in mind» interesting fact: at the assembly level, the number of writes made by a function program is typically roughly the same as the number of writes by an imperative program

4 This Time Understanding the space complexity of functional programs At least two interesting components: the amount of live space at any instant in time the rate of allocation a function call may not change the amount of live space by much but may allocate at a substantial rate because functional programs act by generating new data structures and discarding old ones, they often allocate at a great rate» OCaml garbage collector is optimized with this in mind» interesting fact: at the assembly level, the number of writes made by a function program is typically roughly the same as the number of writes by an imperative program What takes up space? conventional first-order data: tuples, lists, strings, datatypes function representations (closures) the call stack

5 CONVENTIONAL DATA

6 Allocating space Whenever you use a constructor, space is allocated: let rec insert (t:tree) (i:int) = match t with Leaf -> Node (i, Leaf, Leaf) Node (j, left, right) -> if i <= j then Node (j, insert left i, right) else Node (j, left, insert right i)

7 Allocating space Whenever you use a constructor, space is allocated: let rec insert (t:tree) (i:int) = match t with Leaf -> Node (i, Leaf, Leaf) Node (j, left, right) -> if i <= j then Node (j, insert left i, right) else Node (j, left, insert right i) Consider: insert t 21 t

8 Allocating space Whenever you use a constructor, space is allocated: let rec insert (t:tree) (i:int) = match t with Leaf -> Node (i, Leaf, Leaf) Node (j, left, right) -> if i <= j then Node (j, insert left i, right) else Node (j, left, insert right i) Consider: insert t 21 t

9 Allocating space Whenever you use a constructor, space is allocated: let rec insert (t:tree) (i:int) = match t with Leaf -> Node (i, Leaf, Leaf) Node (j, left, right) -> if i <= j then Node (j, insert left i, right) else Node (j, left, insert right i) Consider: insert t 21 t

10 Allocating space Whenever you use a constructor, space is allocated: let rec insert (t:tree) (i:int) = match t with Leaf -> Node (i, Leaf, Leaf) Node (j, left, right) -> if i <= j then Node (j, insert left i, right) else Node (j, left, insert right i) Consider: insert t 21 t

11 Allocating space Whenever you use a constructor, space is allocated: let rec insert (t:tree) (i:int) = match t with Leaf -> Node (i, Leaf, Leaf) Node (j, left, right) -> if i <= j then Node (j, insert left i, right) else Node (j, left, insert right i) Consider: insert t 21 t

12 Allocating space Whenever you use a constructor, space is allocated: let rec insert (t:tree) (i:int) = match t with Leaf -> Node (i, Leaf, Leaf) Node (j, left, right) -> if i <= j then Node (j, insert left i, right) else Node (j, left, insert right i) Consider: insert t 21 t

13 Allocating space Whenever you use a constructor, space is allocated: let rec insert (t:tree) (i:int) = match t with Leaf -> Node (i, Leaf, Leaf) Node (j, left, right) -> if i <= j then Node (j, insert left i, right) else Node (j, left, insert right i) Consider: insert t 21 t

14 Allocating space Whenever you use a constructor, space is allocated: let rec insert (t:tree) (i:int) = match t with Leaf -> Node (i, Leaf, Leaf) Node (j, left, right) -> if i <= j then Node (j, insert left i, right) else Node (j, left, insert right i) Consider: insert t 21 t

15 Allocating space Whenever you use a constructor, space is allocated: let rec insert (t:tree) (i:int) = match t with Leaf -> Node (i, Leaf, Leaf) Node (j, left, right) -> if i <= j then Node (j, insert left i, right) else Node (j, left, insert right i) Total space allocated is proportional to the height of the tree. ~ log n, if tree with n nodes is balanced t

16 Compare let check_option (o:int option) : int option = match o with Some _ -> o None -> failwith found none let check_option (o:int option) : int option = match o with Some j -> Some j None -> failwith found none

17 Compare let check_option (o:int option) : int option = match o with Some _ -> o None -> failwith found none allocates nothing when arg is Some i let check_option (o:int option) : int option = match o with Some j -> Some j None -> failwith found none allocates an option when arg is Some i

18 Compare let cadd (c1:int*int) (c2:int*int) : int*int = let (x1,y1) = c1 in let (x2,y2) = c2 in (x1+x2, y1+y2) let double (c1:int*int) : int*int = let c2 = c1 in cadd c1 c2 let double (c1:int*int) : int*int = cadd c1 c1 let double (c1:int*int) : int*int = let (x1,y1) = c1 in cadd (x1,y1) (x1,y1)

19 Compare let cadd (c1:int*int) (c2:int*int) : int*int = let (x1,y1) = c1 in let (x2,y2) = c2 in (x1+x2, y1+y2) let double (c1:int*int) : int*int = let c2 = c1 in cadd c1 c2 c1 1 2 c2 let double (c1:int*int) : int*int = cadd c1 c1 let double (c1:int*int) : int*int = let (x1,y1) = c1 in cadd (x1,y1) (x1,y1)

20 Compare let cadd (c1:int*int) (c2:int*int) : int*int = let (x1,y1) = c1 in let (x2,y2) = c2 in (x1+x2, y1+y2) let double (c1:int*int) : int*int = let c2 = c1 in cadd c1 c2 let double (c1:int*int) : int*int = cadd c1 c1 c1 1 2 let double (c1:int*int) : int*int = let (x1,y1) = c1 in cadd (x1,y1) (x1,y1)

21 Compare let cadd (c1:int*int) (c2:int*int) : int*int = let (x1,y1) = c1 in let (x2,y2) = c2 in (x1+x2, y1+y2) let double (c1:int*int) : int*int = let c2 = c1 in cadd c1 c2 let double (c1:int*int) : int*int = cadd c1 c1 let double (c1:int*int) : int*int = let (x1,y1) = c1 in cadd (x1,y1) (x1,y1) c1 1 2 arg1 1 2 arg2 1 2

22 Compare let cadd (c1:int*int) (c2:int*int) : int*int = let (x1,y1) = c1 in let (x2,y2) = c2 in (x1+x2, y1+y2) let double (c1:int*int) : int*int = let c2 = c1 in cadd c1 c2 cadd allocates double does not let double (c1:int*int) : int*int = cadd c1 c1 cadd allocates double does not let double (c1:int*int) : int*int = let (x1,y1) = c1 in cadd (x1,y1) (x1,y1) cadd allocates double allocates 2 pairs

23 Compare let cadd (c1:int*int) (c2:int*int) : int*int = let (x1,y1) = c1 in let (x2,y2) = c2 in (x1+x2, y1+y2) let double (c1:int*int) : int*int = let (x1,y1) = c1 in cadd c1 c1 cadd allocates double does not extracts components; does not allocate

24 FUNCTION CLOSURES

25 Consider the following program: Closures let choose (arg:bool * int * int) : int -> int = let (b, x, y) = arg in if b then (fun n -> n + x) else (fun n -> n + y) choose (true, 1, 2)

26 Consider the following program: Closures let choose (arg:bool * int * int) : int -> int = let (b, x, y) = arg in if b then (fun n -> n + x) else (fun n -> n + y) choose (true, 1, 2) It s execution behavior according to the substitution model: choose (true, 1, 2)

27 Consider the following program: Closures let choose (arg:bool * int * int) : int -> int = let (b, x, y) = arg in if b then (fun n -> n + x) else (fun n -> n + y) choose (true, 1, 2) It s execution behavior according to the substitution model: choose (true, 1, 2) let (b, x, y) = (true, 1, 2) in if b then (fun n -> n + x) else (fun n -> n + y)

28 Consider the following program: Closures let choose (arg:bool * int * int) : int -> int = let (b, x, y) = arg in if b then (fun n -> n + x) else (fun n -> n + y) choose (true, 1, 2) It s execution behavior according to the substitution model: choose (true, 1, 2) let (b, x, y) = (true, 1, 2) in if b then (fun n -> n + x) else (fun n -> n + y) if true then (fun n -> n + 1) else (fun n -> n + 2)

29 Consider the following program: Closures let choose (arg:bool * int * int) : int -> int = let (b, x, y) = arg in if b then (fun n -> n + x) else (fun n -> n + y) choose (true, 1, 2) It s execution behavior according to the substitution model: choose (true, 1, 2) let (b, x, y) = (true, 1, 2) in if b then (fun n -> n + x) else (fun n -> n + y) if true then (fun n -> n + 1) else (fun n -> n + 2) (fun n -> n + 1)

30 let choose arg = let (b, x, y) = arg in if b then (fun n -> n + x) else (fun n -> n + y) choose (true, 1, 2) Substitution and Compiled Code

31 Substitution and Compiled Code let choose arg = let (b, x, y) = arg in if b then (fun n -> n + x) else (fun n -> n + y) choose (true, 1, 2) compile choose: mov rb r_arg[0] mov rx r_arg[4] mov ry r_arg[8] compare rb 0... jmp ret main:... jmp choose

32 Substitution and Compiled Code let choose arg = let (b, x, y) = arg in if b then (fun n -> n + x) else (fun n -> n + y) choose (true, 1, 2) execute with substitution let (b, x, y) = (true, 1, 2) in if b then (fun n -> n + x) else (fun n -> n + y) compile choose: mov rb r_arg[0] mov rx r_arg[4] mov ry r_arg[8] compare rb 0... jmp ret main:... jmp choose

33 Substitution and Compiled Code let choose arg = let (b, x, y) = arg in if b then (fun n -> n + x) else (fun n -> n + y) choose (true, 1, 2) execute with substitution let (b, x, y) = (true, 1, 2) in if b then (fun n -> n + x) else (fun n -> n + y) compile choose: mov rb r_arg[0] mov rx r_arg[4] mov ry r_arg[8] compare rb 0... jmp ret main:... jmp choose execute with substitution == generate new code block with parameters replaced by arguments

34 Substitution and Compiled Code let choose arg = let (b, x, y) = arg in if b then (fun n -> n + x) else (fun n -> n + y) choose (true, 1, 2) execute with substitution let (b, x, y) = (true, 1, 2) in if b then (fun n -> n + x) else (fun n -> n + y) compile choose: mov rb r_arg[0] choose_subst: mov rx r_arg[4] mov rb 0xF8[0] mov ry r_arg[8]... jmp ret main:... jmp choose choose: mov rb r_arg[0] mov rx r_arg[4] mov ry r_arg[8] compare rb 0... jmp ret main:... jmp choose execute with substitution == generate new code block with parameters replaced by arguments mov rx 0xF8[4] mov ry 0xF8[8] compare rb 0... jmp ret 0xF8: 0 1 2

35 Substitution and Compiled Code let choose arg = let (b, x, y) = arg in if b then (fun n -> n + x) else (fun n -> n + y) choose (true, 1, 2) execute with substitution let (b, x, y) = (true, 1, 2) in if b then (fun n -> n + x) else (fun n -> n + y) execute with substitution if true then (fun n -> n + 1) else (fun n -> n + 2) compile choose: mov rb r_arg[0] mov rx r_arg[4] mov ry r_arg[8] compare rb 0... jmp ret main:... jmp choose execute with substitution == generate new code block with parameters replaced by arguments choose: mov rb r_arg[0] choose_subst: mov rx r_arg[4] mov rb 0xF8[0] mov ry r_arg[8] mov rx 0xFF44]... choose_subst2: mov ry 0xFF84[8] jmp ret compare 1 0 compare rb main: jmp ret jmp ret... jmp choose 0xF8: 0 1 2

36 What we aren t going to do The substitution model of evaluation is just a model. It says that we generate new code at each step of a computation. We don t do that in reality. Too expensive! The substitution model is a faithful model for reasoning about program correctness but it doesn t help us understand what is going on at the machine-code level that s a good thing! abstraction!! you should almost never think about machine code when writing a program. We invented high-level programming languages so you don t have to. Still, we need to have a more faithful space model in order to understand how to write efficient algorithms.

37 Some functions are easy to implement let add (x:int*int) : int = let (y,z) = x in y + z # argument in r1 # return address in r0 add: ld r2, r1[0] ld r3, r1[4] add r4, r2, r3 jmp r0 # y in r2 # z in r3 # sum in r4 If no functions in ML were nested then compiling ML would be just like compiling C. (Take COS 320 to find out how to do that...)

38 How do we implement functions? Let s remove the nesting and compile them like we compile C. let choose arg = let (b, x, y) = arg in if b then (fun n -> n + x) else (fun n -> n + y)??? let choose arg = let (b, x, y) = arg in if b then f1 else f2 let f1 n = n + x let f2 n = n + y

39 How do we implement functions? Let s remove the nesting and compile them like we compile C. let choose arg = let (b, x, y) = arg in if b then (fun n -> n + x) else (fun n -> n + y)??? let choose arg = let (b, x, y) = arg in if b then f1 else f2 let f1 n = n + x let f2 n = n + y Darn! Doesn t work naively. Nested functions contain free variables. Simple unnesting leaves them undefined.

40 How do we implement functions? We can t define a function like the following using code alone: let f2 n = n + y A closure is a pair of some code and an environment: code let f2 (n,env) = n + env.y {y = 1} environment closure

41 Closure Conversion Closure conversion (also called lambda lifting) converts open, nested functions in to closed, top-level functions. let choose arg = let (b, x, y) = arg in if b then (fun n -> n + x + y) else (fun n -> n + y)

42 Closure Conversion Closure conversion (also called lambda lifting) converts open, nested functions in to closed, top-level functions. let choose arg = let (b, x, y) = arg in if b then (fun n -> n + x + y) else (fun n -> n + y) let choose (arg,env) = let (b, x, y) = arg in if b then (f1, {xe=x; ye=y}) else (f2, {ye=y}) add environment parameter create closures let f1 (n,env) = n + env.xe + env.ye let f2 (n,env) = n + env.ye use environment variables instead of free variables

43 Closure Conversion Closure conversion (also called lambda lifting) converts open, nested functions in to closed, top-level functions. let choose arg = let (b, x, y) = arg in if b then (fun n -> n + x + y) else (fun n -> n + y) let choose (arg,env) = let (b, x, y) = arg in if b then (f1, {xe=x; ye=y}) else (f2, {ye=y}) add environment parameter create closures (choose (true,1,2)) 3 let f1 (n,env) = n + env.xe + env.ye let f2 (n,env) = n + env.ye use environment variables instead of free variables let c_closure = (choose, ()) in (* create closure *) let (c_code, c_cenv) = c_closure in (* extract code, env *) let (f_code, f_env) = c_code ((true,1,2), c_env) in (* call choose code, extract f code, env *) f_code (3, f_env) (* call f code *)

44 Closure Conversion Closure conversion (also called lambda lifting) converts open, nested functions in to closed, top-level functions. let choose arg = let (b, x, y) = arg in if b then (fun n -> n + x + y) else (fun n -> n + y) let choose (arg,env) = let (b, x, y) = arg in if b then (f1, {xe=x; ye=y}) else (f2, {ye=y}) add environment parameter create closures (choose (true,1,2)) 3 let f1 (n,env) = n + env.xe + env.ye let f2 (n,env) = n + env.ye use environment variables instead of free variables let c_closure = (choose, ()) in (* create closure *) let (c_code, c_cenv) = c_closure in (* extract code, env *) let (f_code, f_env) = c_code ((true,1,2), c_env) in (* call choose code, extract f code, env *) f_code (3, f_env) (* call f code *)

45 Closure Conversion Closure conversion (also called lambda lifting) converts open, nested functions in to closed, top-level functions. let choose arg = let (b, x, y) = arg in if b then (fun n -> n + x + y) else (fun n -> n + y) let choose (arg,env) = let (b, x, y) = arg in if b then (f1, {xe=x; ye=y}) else (f2, {ye=y}) add environment parameter create closures (choose (true,1,2)) 3 let f1 (n,env) = n + env.xe + env.ye let f2 (n,env) = n + env.ye use environment variables instead of free variables let c_closure = (choose, ()) in (* create closure *) let (c_code, c_cenv) = c_closure in (* extract code, env *) let (f_code, f_env) = c_code ((true,1,2), c_env) in (* call choose code, extract f code, env *) f_code (3, f_env) (* call f code *)

46 Closure Conversion Closure conversion (also called lambda lifting) converts open, nested functions in to closed, top-level functions. let choose arg = let (b, x, y) = arg in if b then (fun n -> n + x + y) else (fun n -> n + y) let choose (arg,env) = let (b, x, y) = arg in if b then (f1, {xe=x; ye=y}) else (f2, {ye=y}) add environment parameter create closures (choose (true,1,2)) 3 let f1 (n,env) = n + env.xe + env.ye let f2 (n,env) = n + env.ye use environment variables instead of free variables let c_closure = (choose, ()) in (* create closure *) let (c_code, c_cenv) = c_closure in (* extract code, env *) let (f_code, f_env) = c_code ((true,1,2), c_env) in (* call choose code, extract f code, env *) f_code (3, f_env) (* call f code *)

47 One Extra Note: Typing Even though the original, non-closure-converted code was welltyped, the closure-converted code isn t because the environments are different let choose (arg,env) = let (b, x, y) = arg in if b then (f1, F1 {xe=x; ye=y}) else (f2, F2 {ye=y}) let f1 (n,env) = n + env.xe + env.ye let f2 (n,env) = n + env.ye type f1_env = {x1:int; y1:int} type f2_env = {y2:int} type f1_clos = (int * f1_env -> int) * f1_env type f2_clos = (int * f2_env -> int) * f2_env

48 One Extra Note: Typing Even though the original, non-closure-converted code was welltyped, the closure-converted code isn t because the environments are different let choose (arg,env) = let (b, x, y) = arg in if b then (f1, F1 {x1=x; y2=y}) else (f2, F2 {y2=y}) type f1_env = {x1:int; y1:int} type f2_env = {y2:int} let f1 (n,env) = match env with F1 e -> n + e.x1 + e.y2 F2 _ -> failwith "bad env!" let f2 (n,env) = match env with F1 _ -> failwith "bad env!" F2 e -> n + e.y2 type f1_clos = (int * f1_env -> int) * f1_env type f2_clos = (int * f2_env -> int) * f2_env fix I: type env = F1 of f1_env F2 of f2_env type f1_clos = (int * env -> int) * env type f2_clos = (int * env -> int) * env

49 One Extra Note: Typing Even though the original, non-closure-converted code was welltyped, the closure-converted code isn t because the environments are different let choose (arg,env) = let (b, x, y) = arg in if b then (f1, {xe=x; ye=y}) else (f2, {ye=y}) let f1 (n,env) = n + env.xe + env.ye let f2 (n,env) = n + env.ye type f1_env = {xe:int; ye:int} type f2_env = {xe:int} type f1_clos = (int * f1_env -> int) * f1_env type f2_clos = (int * f2_env -> int) * f2_env fix II: type f1_env = {xe:int; ye:int} type f2_env = {xe:int} type f1_clos = exists env.(int * env -> int) * env type f2_clos = exists env.(int * env -> int) * env

50 One Extra Note: Typing Even though the original, non-closure-converted code was welltyped, the closure-converted code isn t because the environments are different let choose (arg,env) = let (b, x, y) = arg in if b then (f1, {xe=x; ye=y}) else (f2, {ye=y}) let f1 (n,env) = n + env.xe + env.ye let f2 (n,env) = n + env.ye From System F to Typed Assembly Language, -- Morrisett, Walker et al. type f1_env = {xe:int; ye:int} type f2_env = {xe:int} type f1_clos = (int * f1_env -> int) * f1_env type f2_clos = (int * f2_env -> int) * f2_env fix II: type f1_env = {xe:int; ye:int} type f2_env = {xe:int} type f1_clos = exists env.(int * env -> int) * env type f2_clos = exists env.(int * env -> int) * env

51 map has a universal polymorphic type: Aside: Existential Types map : ('a -> 'b) -> 'a list -> 'b list "for all types 'a and for all types 'b, " when we closure-convert a function that has type int -> int, we get a function with existential polymorphic type: exists 'a. ((int * 'a) -> int) * 'a "there exists some type 'a such that, " In OCaml, we can approximate existential types using datatypes (a data type allows you to say "there exists a type 'a drawn from one of the following finite number of options." In Haskell, you've got the real thing.

52 Closure Conversion: Summary (before) (after) All function definitions equipped with extra env parameter: let f arg =... let f_code (arg, env) =... All free variables obtained from environment: x env.cx All functions values paired with environment: f (f_code, {ve1=v1;...; ven=vn}) All function calls extract code and environment and call code: f e let (f_code, f_env) = f in f_code (e, f_env)

53 The Space Cost of Closures The space cost of a closure = the cost of the pair of code and environment pointers + the cost of the data referred to by function free variables

54 TAIL CALLS AND CONTINUATIONS

55 Some Innocuous Code (* sum of 0..n *) let rec sum_to (n:int) : int = if n > 0 then n + sum_to (n-1) else 0 let big_int = sum big_int Let s try it. (Go to tail.ml)

56 Some Other Code Four functions: Green works on big inputs; Red doesn t. let sum_to2 (n: int) : int = let rec aux (n:int) (a:int) : int = if n > 0 then aux (n-1) (a+n) else a in aux n 0 let rec sum_to (n:int) : int = if n > 0 then n + sum_to (n-1) else 0 let rec sum2 (l:int list) : int = match l with [] -> 0 hd::tail -> hd + sum2 tail let sum (l:int list) : int = let rec aux (l:int list) (a:int) : int = match l with [] -> a hd::tail -> aux tail (a+hd) in aux l 0

57 Some Other Code Four functions: Green works on big inputs; Red doesn t. let sum_to2 (n: int) : int = let rec aux (n:int) (a:int) : int = if n > 0 then aux (n-1) (a+n) else a in aux n 0 let rec sum_to (n:int) : int = if n > 0 then n + sum_to (n-1) else 0 code that works: no computation after recursive function call let rec sum2 (l:int list) : int = match l with [] -> 0 hd::tail -> hd + sum2 tail let sum (l:int list) : int = let rec aux (l:int list) (a:int) : int = match l with [] -> a hd::tail -> aux tail (a+hd) in aux l 0

58 Tail Recursion A tail-recursive function is a function that does no work after it calls itself recursively. (* sum of 0..n *) let sum_to2 (n: int) : int = let rec aux (n:int)(a:int) : int = if n > 0 then aux (n-1) (a+n) else a in aux n 0

59 Tail Recursion A tail-recursive function is a function that does no work after it calls itself recursively. Tail-recursive: sum_to aux aux aux aux 0 ( ) (* sum of 0..n *) let sum_to2 (n: int) : int = let rec aux (n:int)(a:int) : int = if n > 0 then aux (n-1) (a+n) else a in aux n 0 constant size expression (addition overflow occurred at some point)

60 Tail Recursion A tail-recursive function is a function that does no work after it calls itself recursively. Not tail-recursive: sum_to sum_to sum_to sum_to add it all back up... (* sum of 0..n *) let rec sum_to (n:int) : int = if n > 0 then n + sum_to (n-1) else 0 let big_int = sum big_int expression grows at every recursive call

61 Memory is partitioned: Stack and Heap heap space (big!) stack space (small!)

62 Data Needed on Return Saved on Stack sum_to the stack every non-tail call puts the data from the calling context on the stack not much space left! will run out soon!

63 Question Can any non-tail-recursive function be transformed in to a tailrecursive one? let rec sum_to (n: int) : int = if n > 0 then n + sum_to (n-1) else 0 human ingenuity not only is sum2 tail-recursive but it reimplements an algorithm that took linear space (on the stack) using an algorithm that executes in constant space! let sum_to2 (n: int) : int = let rec aux (n:int)(a:int) : int = if n > 0 then aux (n-1) (a+n) else a in aux n 0

64 Question Can any non-tail-recursive function be transformed in to a tailrecursive one? Yes, if we can capture the differential between a tail-recursive function and a non-tail-recursive one. let rec sum (l:int list) : int = match l with [] -> 0 hd::tail -> hd + sum tail Idea: Focus on what happens after the recursive call.

65 Question Can any non-tail-recursive function be transformed in to a tailrecursive one? Yes, if we can capture the differential between a tail-recursive function and a non-tail-recursive one. let rec sum (l:int list) : int = match l with [] -> 0 hd::tail -> hd + sum tail what happens next Idea: Focus on what happens after the recursive call. Extracting that piece: hd + How do we capture it?

66 Question How do we capture that computation? hd + fun s -> hd + s

67 Question How do we capture that computation? hd + fun s -> hd + s let rec sum (l:int list) : int = match l with [] -> 0 hd::tail -> hd + sum tail type cont = int -> int let rec sum_cont (l:int list) (k:cont): int = match l with [] -> k 0 hd::tail -> sum_cont tail (fun s ->???)

68 Question How do we capture that computation? hd + fun s -> hd + s let rec sum (l:int list) : int = match l with [] -> 0 hd::tail -> hd + sum tail type cont = int -> int let rec sum_cont (l:int list) (k:cont): int = match l with [] -> k 0 hd::tail -> sum_cont tail (fun s -> k (hd + s))

69 Question How do we capture that computation? hd + fun s -> hd + s let rec sum (l:int list) : int = match l with [] -> 0 hd::tail -> hd + sum tail type cont = int -> int let rec sum_cont (l:int list) (k:cont): int = match l with [] -> k 0 hd::tail -> sum_cont tail (fun s -> k (hd + s)) let sum (l:int list) : int =??

70 Question How do we capture that computation? hd + fun s -> hd + s let rec sum (l:int list) : int = match l with [] -> 0 hd::tail -> hd + sum tail type cont = int -> int let rec sum_cont (l:int list) (k:cont): int = match l with [] -> k 0 hd::tail -> sum_cont tail (fun s -> k (hd + s)) let sum (l:int list) : int = sum_cont l (fun s -> s)

71 Execution type cont = int -> int let rec sum_cont (l:int list) (k:cont): int = match l with [] -> k 0 hd::tail -> sum_cont tail (fun s -> k (hd + s)) let sum (l:int list) : int = sum_cont l (fun s -> s) sum [1;2]

72 Execution type cont = int -> int let rec sum_cont (l:int list) (k:cont): int = match l with [] -> k 0 hd::tail -> sum_cont tail (fun s -> k (hd + s)) let sum (l:int list) : int = sum_cont l (fun s -> s) sum [1;2] sum_cont [1;2] (fun s -> s)

73 Execution type cont = int -> int let rec sum_cont (l:int list) (k:cont): int = match l with [] -> k 0 hd::tail -> sum_cont tail (fun s -> k (hd + s)) let sum (l:int list) : int = sum_cont l (fun s -> s) sum [1;2] sum_cont [1;2] (fun s -> s) sum_cont [2] (fun s -> (fun s -> s) (1 + s))

74 Execution type cont = int -> int let rec sum_cont (l:int list) (k:cont): int = match l with [] -> k 0 hd::tail -> sum_cont tail (fun s -> k (hd + s)) let sum (l:int list) : int = sum_cont l (fun s -> s) sum [1;2] sum_cont [1;2] (fun s -> s) sum_cont [2] (fun s -> (fun s -> s) (1 + s)) sum_cont [] (fun s -> (fun s -> (fun s -> s) (1 + s)) (2 + s))

75 Execution type cont = int -> int let rec sum_cont (l:int list) (k:cont): int = match l with [] -> k 0 hd::tail -> sum_cont tail (fun s -> k (hd + s)) let sum (l:int list) : int = sum_cont l (fun s -> s) sum [1;2] sum_cont [1;2] (fun s -> s) sum_cont [2] (fun s -> (fun s -> s) (1 + s)) sum_cont [] (fun s -> (fun s -> (fun s -> s) (1 + s)) (2 + s)) (fun s -> (fun s -> (fun s -> s) (1 + s)) (2 + s)) 0

76 Execution type cont = int -> int let rec sum_cont (l:int list) (k:cont): int = match l with [] -> k 0 hd::tail -> sum_cont tail (fun s -> k (hd + s)) let sum (l:int list) : int = sum_cont l (fun s -> s) sum [1;2] sum_cont [1;2] (fun s -> s) sum_cont [2] (fun s -> (fun s -> s) (1 + s)) sum_cont [] (fun s -> (fun s -> (fun s -> s) (1 + s)) (2 + s)) (fun s -> (fun s -> (fun s -> s) (1 + s)) (2 + s)) 0 (fun s -> (fun s -> s) (1 + s)) (2 + 0))

77 Execution type cont = int -> int let rec sum_cont (l:int list) (k:cont): int = match l with [] -> k 0 hd::tail -> sum_cont tail (fun s -> k (hd + s)) let sum (l:int list) : int = sum_cont l (fun s -> s) sum [1;2] sum_cont [1;2] (fun s -> s) sum_cont [2] (fun s -> (fun s -> s) (1 + s)) sum_cont [] (fun s -> (fun s -> (fun s -> s) (1 + s)) (2 + s)) (fun s -> (fun s -> (fun s -> s) (1 + s)) (2 + s)) 0 (fun s -> (fun s -> s) (1 + s)) (2 + 0)) (fun s -> s) (1 + (2 + 0))

78 Execution type cont = int -> int let rec sum_cont (l:int list) (k:cont): int = match l with [] -> k 0 hd::tail -> sum_cont tail (fun s -> k (hd + s)) let sum (l:int list) : int = sum_cont l (fun s -> s) sum [1;2] sum_cont [1;2] (fun s -> s) sum_cont [2] (fun s -> (fun s -> s) (1 + s)) sum_cont [] (fun s -> (fun s -> (fun s -> s) (1 + s)) (2 + s)) (fun s -> (fun s -> (fun s -> s) (1 + s)) (2 + s)) 0 (fun s -> (fun s -> s) (1 + s)) (2 + 0)) (fun s -> s) (1 + (2 + 0)) 1 + (2 + 0) 3

79 Question type cont = int -> int let rec sum_cont (l:int list) (k:cont): int = match l with [] -> k 0 hd::tail -> sum_cont tail (fun s -> k (hd + s)) let sum (l:int list) : int = sum_cont l (fun s -> s) sum [1;2] sum_cont [1;2] (fun s -> s) sum_cont [2] (fun s -> (fun s -> s) (1 + s)) sum_cont [] (fun s -> (fun s -> (fun s -> s) (1 + s)) (2 + s))... 3 Where did the stack space go?

80 CPS CPS: short for Continuation-Passing Style Every function takes a continuation as an argument that expresses "what to do next" CPS functions only call other functions as the last thing they do

81 CORRECTNESS OF A CPS TRANSFORM

82 type cont = int -> int Are the two functions the same? let rec sum_cont (l:int list) (k:cont): int = match l with [] -> k 0 hd::tail -> sum_cont tail (fun s -> k (hd + s)) let sum2 (l:int list) : int = sum_cont l (fun s -> s) let rec sum (l:int list) : int = match l with [] -> 0 hd::tail -> hd + sum tail Here, it is really pretty tricky to be sure you've done it right if you don't prove it. Let's try to prove this theorem and see what happens: for all l:int list, sum_cont l (fun x => x) == sum l

83 Attempting a Proof for all l:int list, sum_cont l (fun s -> s) == sum l Proof: By induction on the structure of the list l. case l = []... case: hd::tail IH: sum_cont tail (fun s -> s) == sum tail

84 Attempting a Proof for all l:int list, sum_cont l (fun s -> s) == sum l Proof: By induction on the structure of the list l. case l = []... case: hd::tail IH: sum_cont tail (fun s -> s) == sum tail == sum_cont (hd::tail) (fun s -> s)

85 Attempting a Proof for all l:int list, sum_cont l (fun s -> s) == sum l Proof: By induction on the structure of the list l. case l = []... case: hd::tail IH: sum_cont tail (fun s -> s) == sum tail sum_cont (hd::tail) (fun s -> s) == sum_cont tail (fn s' -> (fn s -> s) (hd + s')) (eval)

86 Attempting a Proof for all l:int list, sum_cont l (fun s -> s) == sum l Proof: By induction on the structure of the list l. case l = []... case: hd::tail IH: sum_cont tail (fun s -> s) == sum tail sum_cont (hd::tail) (fun s -> s) == sum_cont tail (fn s' -> (fn s -> s) (hd + s')) (eval) == sum_cont tail (fn s' -> hd + s') (eval -- hd + s' valuable)

87 Need to Generalize the Theorem and IH for all l:int list, sum_cont l (fun s -> s) == sum l Proof: By induction on the structure of the list l. case l = []... case: hd::tail IH: sum_cont tail (fun s -> s) == sum tail sum_cont (hd::tail) (fun s -> s) == sum_cont tail (fn s' -> (fn s -> s) (hd + s')) (eval) == sum_cont tail (fn s' -> hd + s') (eval -- hd + s' valuable) == darn! we'd like to use the IH, but we can't! we might like: not the identity continuation (fun s -> s) like the IH requires sum_cont tail (fn s' -> hd + s') == sum tail... but that's not even true

88 Need to Generalize the Theorem and IH for all l:int list, for all k:int->int, sum_cont l k == k (sum l)

89 Need to Generalize the Theorem and IH for all l:int list, for all k:int->int, sum_cont l k == k (sum l) Proof: By induction on the structure of the list l. case l = [] must prove: for all k:int->int, sum_cont [] k == k (sum [])

90 Need to Generalize the Theorem and IH for all l:int list, for all k:int->int, sum_cont l k == k (sum l) Proof: By induction on the structure of the list l. case l = [] must prove: for all k:int->int, sum_cont [] k == k (sum []) pick an arbitrary k:

91 Need to Generalize the Theorem and IH for all l:int list, for all k:int->int, sum_cont l k == k (sum l) Proof: By induction on the structure of the list l. case l = [] must prove: for all k:int->int, sum_cont [] k == k (sum []) pick an arbitrary k: sum_cont [] k

92 Need to Generalize the Theorem and IH for all l:int list, for all k:int->int, sum_cont l k == k (sum l) Proof: By induction on the structure of the list l. case l = [] must prove: for all k:int->int, sum_cont [] k == k (sum []) pick an arbitrary k: sum_cont [] k == match [] with [] -> k 0 hd::tail ->... (eval) == k 0 (eval)

93 Need to Generalize the Theorem and IH for all l:int list, for all k:int->int, sum_cont l k == k (sum l) Proof: By induction on the structure of the list l. case l = [] must prove: for all k:int->int, sum_cont [] k == k (sum []) pick an arbitrary k: sum_cont [] k == match [] with [] -> k 0 hd::tail ->... (eval) == k 0 (eval) == k (sum [])

94 Need to Generalize the Theorem and IH for all l:int list, for all k:int->int, sum_cont l k == k (sum l) Proof: By induction on the structure of the list l. case l = [] must prove: for all k:int->int, sum_cont [] k == k (sum []) pick an arbitrary k: sum_cont [] k == match [] with [] -> k 0 hd::tail ->... (eval) == k 0 (eval) == k (0) (eval, reverse) == k (match [] with [] -> 0 hd::tail ->...) (eval, reverse) == k (sum []) case done!

95 Need to Generalize the Theorem and IH for all l:int list, for all k:int->int, sum_cont l k == k (sum l) Proof: By induction on the structure of the list l. case l = [] ===> done! case l = hd::tail IH: for all k':int->int, sum_cont tail k' == k' (sum tail) Must prove: for all k:int->int, sum_cont (hd::tail) k == k (sum (hd::tail))

96 Need to Generalize the Theorem and IH for all l:int list, for all k:int->int, sum_cont l k == k (sum l) Proof: By induction on the structure of the list l. case l = [] ===> done! case l = hd::tail IH: for all k':int->int, sum_cont tail k' == k' (sum tail) Must prove: for all k:int->int, sum_cont (hd::tail) k == k (sum (hd::tail)) Pick an arbitrary k, sum_cont (hd::tail) k

97 Need to Generalize the Theorem and IH for all l:int list, for all k:int->int, sum_cont l k == k (sum l) Proof: By induction on the structure of the list l. case l = [] ===> done! case l = hd::tail IH: for all k':int->int, sum_cont tail k' == k' (sum tail) Must prove: for all k:int->int, sum_cont (hd::tail) k == k (sum (hd::tail)) Pick an arbitrary k, sum_cont (hd::tail) k == sum_cont tail (fun s -> k (hd + x)) (eval)

98 Need to Generalize the Theorem and IH for all l:int list, for all k:int->int, sum_cont l k == k (sum l) Proof: By induction on the structure of the list l. case l = [] ===> done! case l = hd::tail IH: for all k':int->int, sum_cont tail k' == k' (sum tail) Must prove: for all k:int->int, sum_cont (hd::tail) k == k (sum (hd::tail)) Pick an arbitrary k, sum_cont (hd::tail) k == sum_cont tail (fun s -> k (hd + x)) (eval) == (fun s -> k (hd + s)) (sum tail) (IH with IH quantifier k' replaced with (fun x -> k (hd+x))

99 Need to Generalize the Theorem and IH for all l:int list, for all k:int->int, sum_cont l k == k (sum l) Proof: By induction on the structure of the list l. case l = [] ===> done! case l = hd::tail IH: for all k':int->int, sum_cont tail k' == k' (sum tail) Must prove: for all k:int->int, sum_cont (hd::tail) k == k (sum (hd::tail)) Pick an arbitrary k, sum_cont (hd::tail) k == sum_cont tail (fun s -> k (hd + x)) (eval) == (fun s -> k (hd + s)) (sum tail) (IH with IH quantifier k' replaced with (fun x -> k (hd+x)) == k (hd + (sum tail)) (eval, since sum total and and sum tail valuable)

100 Need to Generalize the Theorem and IH for all l:int list, for all k:int->int, sum_cont l k == k (sum l) Proof: By induction on the structure of the list l. case l = [] ===> done! case l = hd::tail IH: for all k':int->int, sum_cont tail k' == k' (sum tail) Must prove: for all k:int->int, sum_cont (hd::tail) k == k (sum (hd::tail)) Pick an arbitrary k, sum_cont (hd::tail) k == sum_cont tail (fun s -> k (hd + x)) (eval) == (fun s -> k (hd + s)) (sum tail) (IH with IH quantifier k' replaced with (fun x -> k (hd+x)) == k (hd + (sum tail)) (eval, since sum total and and sum tail valuable) == k (sum (hd:tail)) (eval sum, reverse) case done! QED!

101 Finishing Up Ok, now what we have is a proof of this theorem: for all l:int list, for all k:int->int, sum_cont l k == k (sum l) We can use that general theorem to get what we really want: for all l:int list, sum2 l == sum_cont l (fun s -> s) (by eval sum2) == (fun s -> s) (sum l) (by theorem, instantiating k with (fun s -> s) == sum l So, we've show that the function sum2, which is tail-recursive, is functionally equivalent to the non-tail-recursive function sum.

102 SUMMARY

103 Summary of the CPS Proof We tried to prove the specific theorem we wanted: for all l:int list, sum_cont l (fun s -> s) == sum l But it didn't work because in the middle of the proof, the IH didn't apply -- inside our function we had the wrong kind of continuation -- not (fun s -> s) like our IH required. So we had to prove a more general theorem about all continuations. for all l:int list, for all k:int->int, sum_cont l k == k (sum l) This is a common occurrence -- generalizing the induction hypothesis -- and it requires human ingenuity. It's why proving theorems is hard. It's also why writing programs is hard -- you have to make the proofs and programs work more generally, around every iteration of a loop.

104 Overall Summary We developed techniques for reasoning about the space costs of functional programs the cost of manipulating data types like tuples and trees the cost of allocating and using function closures the cost of tail-recursive and non-tail-recursive functions We also talked about some important program transformations: closure conversion makes nested functions with free variables in to pairs of closed code and environment the continuation-passing style (CPS) transformation turns non-tailrecursive functions in to tail-recursive ones that use no stack space the stack gets moved in to the function closure since stack space is often small compared with heap space, it is often necessary to use continuations and tail recursion but full CPS-converted programs are unreadable: use judgement

105 Challenge: CPS Convert the incr function type tree = Leaf Node of int * tree * tree let rec incr (t:tree) (i:int) : tree = match t with Leaf -> Leaf Node (j,left,right) -> Node (i+j, incr left i, incr right i) (see solution after the next slide)

106 END

107 CPS Convert the incr function type tree = Leaf Node of int * tree * tree let rec incr (t:tree) (i:int) : tree = match t with Leaf -> Leaf Node (j,left,right) -> Node (i+j, incr left i, incr right i) type cont = tree -> tree let rec incr_cps (t:tree) (i:int) (k:cont) : tree = match t with Leaf -> k Leaf Node (j,left,right) ->...

108 type tree = Leaf Node of int * tree * tree let rec incr (t:tree) (i:int) : tree = match t with Leaf -> Leaf Node (j,left,right) -> Node (i+j, incr left i, incr right i) first continuation: Node (i+j,, incr right i) second continuation: Node (i+j, left_done, )

109 type tree = Leaf Node of int * tree * tree let rec incr (t:tree) (i:int) : tree = match t with Leaf -> Leaf Node (j,left,right) -> Node (i+j, incr i left, incr i right) first continuation: fun left_done -> Node (i+j, left_done, incr right i) second continuation: fun right_done -> k (Node (i+j, left_done, right_done))

110 type tree = Leaf Node of int * tree * tree let rec incr (t:tree) (i:int) : tree = match t with Leaf -> Leaf Node (j,left,right) -> Node (i+j, incr left i, incr right i) second continuation inside first continuation: fun left_done -> let k2 = (fun right_done -> k (Node (i+j, left_done, right_done)) ) in incr right i k2

111 type tree = Leaf Node of int * tree * tree let rec incr (t:tree) (i:int) : tree = match t with Leaf -> Leaf Node (j,left,right) -> Node (i+j, incr left i, incr right i) type cont = tree -> tree let rec incr_cps (t:tree) (i:int) (k:cont) : tree = match t with Leaf -> k Leaf Node (j,left,right) -> let k1 = (fun left_done -> let k2 = (fun right_done -> k (Node (i+j, left_done, right_done))) in incr_cps right i k2 ) in incr_cps left i k1 let incr_tail (t:tree) (i:int) : tree = incr_cps t i (fun t -> t)

Con$nuing CPS. COS 326 David Walker Princeton University

Con$nuing CPS. COS 326 David Walker Princeton University Con$nuing CPS COS 326 David Walker Princeton University Last Time We saw that code like this could take up a lot of stack space: let rec sum_to (n:int) : int = if n > 0 then n + sum_to (n-1) else 0 Last

More information

A Func'onal Space Model

A Func'onal Space Model A Func'onal Space Model COS 26 David Walker Princeton University slides copyright 2017 David Walker permission granted to reuse these slides for non-commercial educa'onal purposes 2 Because Halloween draws

More information

Modules and Representation Invariants

Modules and Representation Invariants Modules and Representation Invariants COS 326 Andrew W. Appel Princeton University slides copyright 2013-2015 David Walker and Andrew W. Appel In previous classes: Reasoning about individual OCaml expressions.

More information

Programming Languages

Programming Languages CSE 130 : Winter 2009 Programming Languages News PA 2 out, and due Mon 1/26 5pm Lecture 5: Functions and Datatypes t UC San Diego Recap: Environments Phone book Variables = names Values = phone number

More information

Thinking Induc,vely. COS 326 David Walker Princeton University

Thinking Induc,vely. COS 326 David Walker Princeton University Thinking Induc,vely COS 326 David Walker Princeton University slides copyright 2013-2015 David Walker and Andrew W. Appel permission granted to reuse these slides for non-commercial educa,onal purposes

More information

Variables and Bindings

Variables and Bindings 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

More information

Fall Recursion and induction. Stephen Brookes. Lecture 4

Fall Recursion and induction. Stephen Brookes. Lecture 4 15-150 Fall 2018 Stephen Brookes Lecture 4 Recursion and induction Last time Specification format for a function F type assumption guarantee (REQUIRES) (ENSURES) For all (properly typed) x satisfying the

More information

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

News. Programming Languages. Recap. Recap: Environments. Functions. of functions: Closures. CSE 130 : Fall Lecture 5: Functions and Datatypes CSE 130 : Fall 2007 Programming Languages News PA deadlines shifted PA #2 now due 10/24 (next Wed) Lecture 5: Functions and Datatypes Ranjit Jhala UC San Diego Recap: Environments Phone book Variables

More information

Lecture 6: Sequential Sorting

Lecture 6: Sequential Sorting 15-150 Lecture 6: Sequential Sorting Lecture by Dan Licata February 2, 2012 Today s lecture is about sorting. Along the way, we ll learn about divide and conquer algorithms, the tree method, and complete

More information

Recap: Functions as first-class values

Recap: Functions as first-class values Recap: Functions as first-class values Arguments, return values, bindings What are the benefits? Parameterized, similar functions (e.g. Testers) Creating, (Returning) Functions Iterator, Accumul, Reuse

More information

Compilers: The goal. Safe. e : ASM

Compilers: The goal. Safe. e : ASM Compilers: The goal What s our goal with compilers? Take a high level language, turn it into a low level language In a semantics preserving way. e : ML Safe e : ASM 1 Compilers: The goal What s our goal

More information

Closures. Mooly Sagiv. Michael Clarkson, Cornell CS 3110 Data Structures and Functional Programming

Closures. Mooly Sagiv. Michael Clarkson, Cornell CS 3110 Data Structures and Functional Programming Closures Mooly Sagiv Michael Clarkson, Cornell CS 3110 Data Structures and Functional Programming Summary 1. Predictive Parsing 2. Large Step Operational Semantics (Natural) 3. Small Step Operational Semantics

More information

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

Recap. Recap. If-then-else expressions. If-then-else expressions. If-then-else expressions. If-then-else expressions Recap Epressions (Synta) Compile-time Static Eec-time Dynamic Types (Semantics) Recap Integers: +,-,* floats: +,-,* Booleans: =,

More information

Thinking Induc,vely. COS 326 David Walker Princeton University

Thinking Induc,vely. COS 326 David Walker Princeton University Thinking Induc,vely COS 326 David Walker Princeton University slides copyright 2017 David Walker permission granted to reuse these slides for non-commercial educa,onal purposes Administra,on 2 Assignment

More information

Closures. Mooly Sagiv. Michael Clarkson, Cornell CS 3110 Data Structures and Functional Programming

Closures. Mooly Sagiv. Michael Clarkson, Cornell CS 3110 Data Structures and Functional Programming Closures Mooly Sagiv Michael Clarkson, Cornell CS 3110 Data Structures and Functional Programming t ::= x x. t t t Call-by-value big-step Operational Semantics terms variable v ::= values abstraction x.

More information

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

INF 212 ANALYSIS OF PROG. LANGS FUNCTION COMPOSITION. Instructors: Crista Lopes Copyright Instructors. INF 212 ANALYSIS OF PROG. LANGS FUNCTION COMPOSITION Instructors: Crista Lopes Copyright Instructors. Topics Recursion Higher-order functions Continuation-Passing Style Monads (take 1) Identity Monad Maybe

More information

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

Tuples. CMSC 330: Organization of Programming Languages. Examples With Tuples. Another Example CMSC 330: Organization of Programming Languages OCaml 2 Higher Order Functions Tuples Constructed using (e1,..., en) Deconstructed using pattern matching Patterns involve parens and commas, e.g., (p1,p2,

More information

CS 4110 Programming Languages & Logics. Lecture 35 Typed Assembly Language

CS 4110 Programming Languages & Logics. Lecture 35 Typed Assembly Language CS 4110 Programming Languages & Logics Lecture 35 Typed Assembly Language 1 December 2014 Announcements 2 Foster Office Hours today 4-5pm Optional Homework 10 out Final practice problems out this week

More information

Verification of an ML compiler. Lecture 3: Closures, closure conversion and call optimisations

Verification of an ML compiler. Lecture 3: Closures, closure conversion and call optimisations Verification of an ML compiler Lecture 3: Closures, closure conversion and call optimisations Marktoberdorf Summer School MOD 2017 Magnus O. Myreen, Chalmers University of Technology Implementing the ML

More information

The Art of Recursion: Problem Set 10

The Art of Recursion: Problem Set 10 The Art of Recursion: Problem Set Due Tuesday, November Tail recursion A recursive function is tail recursive if every recursive call is in tail position that is, the result of the recursive call is immediately

More information

Scope, Functions, and Storage Management

Scope, Functions, and Storage Management Scope, Functions, and Storage Management Implementing Functions and Blocks cs3723 1 Simplified Machine Model (Compare To List Abstract Machine) Registers Code Data Program Counter (current instruction)

More information

Lambda Calculus: Implementation Techniques and a Proof. COS 441 Slides 15

Lambda Calculus: Implementation Techniques and a Proof. COS 441 Slides 15 Lambda Calculus: Implementation Techniques and a Proof COS 441 Slides 15 Last Time: The Lambda Calculus A language of pure functions: values e ::= x \x.e e e v ::= \x.e With a call-by-value operational

More information

CS 11 Ocaml track: lecture 2

CS 11 Ocaml track: lecture 2 Today: CS 11 Ocaml track: lecture 2 comments algebraic data types more pattern matching records polymorphic types ocaml libraries exception handling Previously... ocaml interactive interpreter compiling

More information

A Functional Evaluation Model

A Functional Evaluation Model A Functional Evaluation Model COS 326 Andrew W. Appel Princeton University slides copyright 2013-2015 David Walker and Andrew W. Appel A Functional Evaluation Model In order to be able to write a program,

More information

Mini-ML. CS 502 Lecture 2 8/28/08

Mini-ML. CS 502 Lecture 2 8/28/08 Mini-ML CS 502 Lecture 2 8/28/08 ML This course focuses on compilation techniques for functional languages Programs expressed in Standard ML Mini-ML (the source language) is an expressive core subset of

More information

INF 102 CONCEPTS OF PROG. LANGS FUNCTIONAL COMPOSITION. Instructors: James Jones Copyright Instructors.

INF 102 CONCEPTS OF PROG. LANGS FUNCTIONAL COMPOSITION. Instructors: James Jones Copyright Instructors. INF 102 CONCEPTS OF PROG. LANGS FUNCTIONAL COMPOSITION Instructors: James Jones Copyright Instructors. Topics Recursion Higher-order functions Continuation-Passing Style Monads (take 1) Identity Monad

More information

Begin at the beginning

Begin at the beginning Begin at the beginning Expressions (Syntax) Exec-time Dynamic Values (Semantics) Compile-time Static Types 1. Programmer enters expression 2. ML checks if expression is well-typed Using a precise set of

More information

Chapter 11 :: Functional Languages

Chapter 11 :: Functional Languages Chapter 11 :: Functional Languages Programming Language Pragmatics Michael L. Scott Copyright 2016 Elsevier 1 Chapter11_Functional_Languages_4e - Tue November 21, 2017 Historical Origins The imperative

More information

CS 11 Haskell track: lecture 1

CS 11 Haskell track: lecture 1 CS 11 Haskell track: lecture 1 This week: Introduction/motivation/pep talk Basics of Haskell Prerequisite Knowledge of basic functional programming e.g. Scheme, Ocaml, Erlang CS 1, CS 4 "permission of

More information

Complexity, Induction, and Recurrence Relations. CSE 373 Help Session 4/7/2016

Complexity, Induction, and Recurrence Relations. CSE 373 Help Session 4/7/2016 Complexity, Induction, and Recurrence Relations CSE 373 Help Session 4/7/2016 Big-O Definition Definition: g(n) is in O( f(n) ) if there exist positive constants c and n0 such that g(n) c f(n) for all

More information

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

Tail Recursion: Factorial. Begin at the beginning. How does it execute? Tail recursion. Tail recursive factorial. Tail recursive factorial 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,

More information

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

Side note: Tail Recursion. Begin at the beginning. Side note: Tail Recursion. Base Types. Base Type: int. Base Type: int 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,

More information

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

News. CSE 130: Programming Languages. Environments & Closures. Functions are first-class values. Recap: Functions as first-class values CSE 130: Programming Languages Environments & Closures News PA 3 due THIS Friday (5/1) Midterm NEXT Friday (5/8) Ranjit Jhala UC San Diego Recap: Functions as first-class values Arguments, return values,

More information

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

Booleans (aka Truth Values) Programming Languages and Compilers (CS 421) Booleans and Short-Circuit Evaluation. Tuples as Values. Booleans (aka Truth Values) Programming Languages and Compilers (CS 421) Elsa L Gunter 2112 SC, UIUC https://courses.engr.illinois.edu/cs421/fa2017/cs421d # true;; - : bool = true # false;; - : bool =

More information

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

Background. CMSC 330: Organization of Programming Languages. Useful Information on OCaml language. Dialects of ML. ML (Meta Language) Standard ML CMSC 330: Organization of Programming Languages Functional Programming with OCaml 1 Background ML (Meta Language) Univ. of Edinburgh, 1973 Part of a theorem proving system LCF The Logic of Computable Functions

More information

Anonymous Functions CMSC 330: Organization of Programming Languages

Anonymous Functions CMSC 330: Organization of Programming Languages Anonymous Functions CMSC 330: Organization of Programming Languages Recall code blocks in Ruby (1..10).each { x print x Here, we can think of { x print x as a function OCaml 2 Higher Order Functions 1

More information

COSE212: Programming Languages. Lecture 4 Recursive and Higher-Order Programming

COSE212: Programming Languages. Lecture 4 Recursive and Higher-Order Programming COSE212: Programming Languages Lecture 4 Recursive and Higher-Order Programming Hakjoo Oh 2016 Fall Hakjoo Oh COSE212 2016 Fall, Lecture 4 September 27, 2016 1 / 21 Recursive and Higher-Order Programming

More information

Tail Calls. CMSC 330: Organization of Programming Languages. Tail Recursion. Tail Recursion (cont d) Names and Binding. Tail Recursion (cont d)

Tail Calls. CMSC 330: Organization of Programming Languages. Tail Recursion. Tail Recursion (cont d) Names and Binding. Tail Recursion (cont d) CMSC 330: Organization of Programming Languages Tail Calls A tail call is a function call that is the last thing a function does before it returns let add x y = x + y let f z = add z z (* tail call *)

More information

COP4020 Programming Languages. Functional Programming Prof. Robert van Engelen

COP4020 Programming Languages. Functional Programming Prof. Robert van Engelen COP4020 Programming Languages Functional Programming Prof. Robert van Engelen Overview What is functional programming? Historical origins of functional programming Functional programming today Concepts

More information

Mutation. COS 326 Andrew W. Appel Princeton University. slides copyright David Walker and Andrew W. Appel

Mutation. COS 326 Andrew W. Appel Princeton University. slides copyright David Walker and Andrew W. Appel Mutation COS 326 Andrew W. Appel Princeton University slides copyright 2013-2015 David Walker and Andrew W. Appel Mutation? 2 Reasoning about Mutable State is Hard mutable set insert i s1; f x; member

More information

The Worker/Wrapper Transformation

The Worker/Wrapper Transformation The Worker/Wrapper Transformation Andy Gill 1 Graham Hutton 2 1 The University of Kansas 2 The University of Nottingham March 26th, 2009 Andy Gill, Graham Hutton The Worker/Wrapper Transformation March

More information

Programming Languages and Compilers (CS 421)

Programming Languages and Compilers (CS 421) Programming Languages and Compilers (CS 421) Elsa L Gunter 2112 SC, UIUC http://courses.engr.illinois.edu/cs421 Based in part on slides by Mattox Beckman, as updated by Vikram Adve and Gul Agha 9/18/17

More information

Types, Type Inference and Unification

Types, Type Inference and Unification Types, Type Inference and Unification Mooly Sagiv Slides by Kathleen Fisher and John Mitchell Cornell CS 6110 Summary (Functional Programming) Lambda Calculus Basic ML Advanced ML: Modules, References,

More information

15 150: Principles of Functional Programming. More about Higher-Order Functions

15 150: Principles of Functional Programming. More about Higher-Order Functions 15 150: Principles of Functional Programming More about Higher-Order Functions Michael Erdmann Spring 2018 1 Topics Currying and uncurrying Staging computation Partial evaluation Combinators 2 Currying

More information

n What is its running time? 9/18/17 2 n poor_rev [1,2,3] = n (poor_rev [1] = n ((poor_rev [1] =

n What is its running time? 9/18/17 2 n poor_rev [1,2,3] = n (poor_rev [1] = n ((poor_rev  [1] = Recall Programming Languages and Compilers (CS 421) Elsa L Gunter 2112 SC, UIUC http://courses.engr.illinois.edu/cs421 Based in part on slides by Mattox Beckman, as updated by Vikram Adve and Gul Agha

More information

CIS 120 Midterm I February 16, 2015 SOLUTIONS

CIS 120 Midterm I February 16, 2015 SOLUTIONS CIS 120 Midterm I February 16, 2015 SOLUTIONS 1 1. Substitution semantics (18 points) Circle the final result of simplifying the following OCaml expressions, or Infinite loop if there is no final answer.

More information

CSC 2400: Computing Systems. X86 Assembly: Function Calls"

CSC 2400: Computing Systems. X86 Assembly: Function Calls CSC 24: Computing Systems X86 Assembly: Function Calls" 1 Lecture Goals! Challenges of supporting functions" Providing information for the called function" Function arguments and local variables" Allowing

More information

Writing code that I'm not smart enough to write. A funny thing happened at Lambda Jam

Writing code that I'm not smart enough to write. A funny thing happened at Lambda Jam Writing code that I'm not smart enough to write A funny thing happened at Lambda Jam Background "Let s make a lambda calculator" Rúnar Bjarnason Task: write an interpreter for the lambda calculus Lambda

More information

Closures & Environments. CS4410: Spring 2013

Closures & Environments. CS4410: Spring 2013 Closures & Environments CS4410: Spring 2013 "Functional" Languages: Lisp, Scheme, Miranda, Hope, ML, OCaml, Haskell, Functions are first-class not just for calling can pass to other functions (map), return

More information

CMSC 330: Organization of Programming Languages. Operational Semantics

CMSC 330: Organization of Programming Languages. Operational Semantics CMSC 330: Organization of Programming Languages Operational Semantics Notes about Project 4, Parts 1 & 2 Still due today (7/2) Will not be graded until 7/11 (along with Part 3) You are strongly encouraged

More information

CMSC 330: Organization of Programming Languages. Closures (Implementing Higher Order Functions)

CMSC 330: Organization of Programming Languages. Closures (Implementing Higher Order Functions) CMSC 330: Organization of Programming Languages Closures (Implementing Higher Order Functions) CMSC330 Spring 2018 1 Returning Functions as Results In OCaml you can pass functions as arguments to map,

More information

Functional Languages. Hwansoo Han

Functional Languages. Hwansoo Han Functional Languages Hwansoo Han Historical Origins Imperative and functional models Alan Turing, Alonzo Church, Stephen Kleene, Emil Post, etc. ~1930s Different formalizations of the notion of an algorithm

More information

Theorem Proving Principles, Techniques, Applications Recursion

Theorem Proving Principles, Techniques, Applications Recursion NICTA Advanced Course Theorem Proving Principles, Techniques, Applications Recursion 1 CONTENT Intro & motivation, getting started with Isabelle Foundations & Principles Lambda Calculus Higher Order Logic,

More information

An experiment with variable binding, denotational semantics, and logical relations in Coq. Adam Chlipala University of California, Berkeley

An experiment with variable binding, denotational semantics, and logical relations in Coq. Adam Chlipala University of California, Berkeley A Certified TypePreserving Compiler from Lambda Calculus to Assembly Language An experiment with variable binding, denotational semantics, and logical relations in Coq Adam Chlipala University of California,

More information

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

CSE 341, Autumn 2005, Assignment 3 ML - MiniML Interpreter Due: Thurs October 27, 10:00pm CSE 341, Autumn 2005, Assignment 3 ML - MiniML Interpreter Note: This is a much longer assignment than anything we ve seen up until now. You are given two weeks to complete

More information

Behavioral Equivalence

Behavioral Equivalence Behavioral Equivalence Prof. Clarkson Fall 2015 Today s music: Soul Bossa Nova by Quincy Jones Review Previously in 3110: Functional programming Modular programming Interpreters Imperative and concurrent

More information

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

# true;; - : bool = true. # false;; - : bool = false 9/10/ // = {s (5, hi, 3.2), c 4, a 1, b 5} 9/10/2017 4 Booleans (aka Truth Values) Programming Languages and Compilers (CS 421) Sasa Misailovic 4110 SC, UIUC https://courses.engr.illinois.edu/cs421/fa2017/cs421a # true;; - : bool = true # false;; - : bool

More information

CSE413: Programming Languages and Implementation Racket structs Implementing languages with interpreters Implementing closures

CSE413: Programming Languages and Implementation Racket structs Implementing languages with interpreters Implementing closures CSE413: Programming Languages and Implementation Racket structs Implementing languages with interpreters Implementing closures Dan Grossman Fall 2014 Hi! I m not Hal J I love this stuff and have taught

More information

CMSC330. Objects, Functional Programming, and lambda calculus

CMSC330. Objects, Functional Programming, and lambda calculus CMSC330 Objects, Functional Programming, and lambda calculus 1 OOP vs. FP Object-oriented programming (OOP) Computation as interactions between objects Objects encapsulate mutable data (state) Accessed

More information

Fall 2018 Lecture 1

Fall 2018 Lecture 1 15-150 Fall 2018 Lecture 1 Stephen Brookes 1 Themes functional programming correctness, termination, and performance types, specifications, and proofs evaluation and equivalence referential transparency

More information

(Refer Slide Time: 4:00)

(Refer Slide Time: 4:00) Principles of Programming Languages Dr. S. Arun Kumar Department of Computer Science & Engineering Indian Institute of Technology, Delhi Lecture - 38 Meanings Let us look at abstracts namely functional

More information

Functional Programming. Introduction To Cool

Functional Programming. Introduction To Cool Functional Programming Introduction To Cool #1 Cunning Plan ML Functional Programming Fold Sorting Cool Overview Syntax Objects Methods Types #2 This is my final day... as your... companion... through

More information

D Programming Language

D Programming Language Group 14 Muazam Ali Anil Ozdemir D Programming Language Introduction and Why D? It doesn t come with a religion this is written somewhere along the overview of D programming language. If you actually take

More information

Types and Type Inference

Types and Type Inference Types and Type Inference Mooly Sagiv Slides by Kathleen Fisher and John Mitchell Reading: Concepts in Programming Languages, Revised Chapter 6 - handout on the course homepage Outline General discussion

More information

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

CMSC 330: Organization of Programming Languages. OCaml Expressions and Functions CMSC 330: Organization of Programming Languages OCaml Expressions and Functions CMSC330 Spring 2018 1 Lecture Presentation Style Our focus: semantics and idioms for OCaml Semantics is what the language

More information

Formal Methods of Software Design, Eric Hehner, segment 24 page 1 out of 5

Formal Methods of Software Design, Eric Hehner, segment 24 page 1 out of 5 Formal Methods of Software Design, Eric Hehner, segment 24 page 1 out of 5 [talking head] This lecture we study theory design and implementation. Programmers have two roles to play here. In one role, they

More information

Control in Sequential Languages

Control in Sequential Languages CS 242 2012 Control in Sequential Languages Reading: Chapter 8, Sections 8.1 8.3 (only) Section 7.3 of The Haskell 98 Report, Exception Handling in the I/O Monad, http://www.haskell.org/onlinelibrary/io-13.html

More information

Programming Languages

Programming Languages CSE 130 : Winter 2013 Programming Languages Lecture 3: Crash Course, Datatypes Ranjit Jhala UC San Diego 1 Story So Far... Simple Expressions Branches Let-Bindings... Today: Finish Crash Course Datatypes

More information

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

CSE 413 Midterm, May 6, 2011 Sample Solution Page 1 of 8 Question 1. (12 points) For each of the following, what value is printed? (Assume that each group of statements is executed independently in a newly reset Scheme environment.) (a) (define x 1) (define

More information

Programming Language Pragmatics

Programming Language Pragmatics Chapter 10 :: Functional Languages Programming Language Pragmatics Michael L. Scott Historical Origins The imperative and functional models grew out of work undertaken Alan Turing, Alonzo Church, Stephen

More information

MPRI course 2-4 Functional programming languages Exercises

MPRI course 2-4 Functional programming languages Exercises MPRI course 2-4 Functional programming languages Exercises Xavier Leroy October 13, 2016 Part I: Interpreters and operational semantics Exercise I.1 (**) Prove theorem 2 (the unique decomposition theorem).

More information

CSE341: Programming Languages Lecture 17 Implementing Languages Including Closures. Dan Grossman Autumn 2018

CSE341: Programming Languages Lecture 17 Implementing Languages Including Closures. Dan Grossman Autumn 2018 CSE341: Programming Languages Lecture 17 Implementing Languages Including Closures Dan Grossman Autumn 2018 Typical workflow concrete syntax (string) "(fn x => x + x) 4" Parsing Possible errors / warnings

More information

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

CSE341: Programming Languages Lecture 9 Function-Closure Idioms. Dan Grossman Winter 2013 CSE341: Programming Languages Lecture 9 Function-Closure Idioms Dan Grossman Winter 2013 More idioms We know the rule for lexical scope and function closures Now what is it good for A partial but wide-ranging

More information

CS 4110 Programming Languages & Logics

CS 4110 Programming Languages & Logics CS 4110 Programming Languages & Logics Lecture 38 Typed Assembly Language 30 November 2012 Schedule 2 Monday Typed Assembly Language Wednesday Polymorphism Stack Types Today Compilation Course Review Certi

More information

1: Introduction to Object (1)

1: Introduction to Object (1) 1: Introduction to Object (1) 김동원 2003.01.20 Overview (1) The progress of abstraction Smalltalk Class & Object Interface The hidden implementation Reusing the implementation Inheritance: Reusing the interface

More information

Induction in Coq. Nate Foster Spring 2018

Induction in Coq. Nate Foster Spring 2018 Induction in Coq Nate Foster Spring 2018 Review Previously in 3110: Functional programming in Coq Logic in Coq Curry-Howard correspondence (proofs are programs) Today: Induction in Coq REVIEW: INDUCTION

More information

COS 326 David Walker Princeton University

COS 326 David Walker Princeton University Functional Abstractions over Imperative Infrastructure and Lazy Evaluation COS 326 David Walker Princeton University slides copyright 2013-2015 David Walker and Andrew W. Appel permission granted to reuse

More information

Behavioral Equivalence

Behavioral Equivalence Behavioral Equivalence Prof. Clarkson Fall 2016 Today s music: Soul Bossa Nova by Quincy Jones Review Previously in 3110: Functional programming Modular programming & software engineering Interpreters

More information

Design Issues. Subroutines and Control Abstraction. Subroutines and Control Abstraction. CSC 4101: Programming Languages 1. Textbook, Chapter 8

Design Issues. Subroutines and Control Abstraction. Subroutines and Control Abstraction. CSC 4101: Programming Languages 1. Textbook, Chapter 8 Subroutines and Control Abstraction Textbook, Chapter 8 1 Subroutines and Control Abstraction Mechanisms for process abstraction Single entry (except FORTRAN, PL/I) Caller is suspended Control returns

More information

Functional programming Primer I

Functional programming Primer I Functional programming Primer I COS 320 Compiling Techniques Princeton University Spring 2016 Lennart Beringer 1 Characteristics of functional programming Primary notions: functions and expressions (not

More information

Lists. Michael P. Fourman. February 2, 2010

Lists. Michael P. Fourman. February 2, 2010 Lists Michael P. Fourman February 2, 2010 1 Introduction The list is a fundamental datatype in most functional languages. ML is no exception; list is a built-in ML type constructor. However, to introduce

More information

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

To figure this out we need a more precise understanding of how ML works Announcements: What are the following numbers: 74/2/70/17 (2:30,2:30,3:35,7:30) PS2 due Thursday 9/20 11:59PM Guest lecture on Tuesday 9/25 o No RDZ office hours next Friday, I am on travel A brief comment

More information

CS Lecture 7: The dynamic environment. Prof. Clarkson Spring Today s music: Down to Earth by Peter Gabriel from the WALL-E soundtrack

CS Lecture 7: The dynamic environment. Prof. Clarkson Spring Today s music: Down to Earth by Peter Gabriel from the WALL-E soundtrack CS 3110 Lecture 7: The dynamic environment Prof. Clarkson Spring 2015 Today s music: Down to Earth by Peter Gabriel from the WALL-E soundtrack Review Course so far: Syntax and semantics of (most of) OCaml

More information

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

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 Recap: ML s Holy Trinity Expressions (Syntax) Exec-time Dynamic Values (Semantics) Datatypes Compile-time Static Types Ranjit Jhala UC San Diego 1. Programmer enters expression

More information

CSCI-GA Scripting Languages

CSCI-GA Scripting Languages CSCI-GA.3033.003 Scripting Languages 12/02/2013 OCaml 1 Acknowledgement The material on these slides is based on notes provided by Dexter Kozen. 2 About OCaml A functional programming language All computation

More information

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

CSE 130 Programming Languages. Datatypes. Ranjit Jhala UC San Diego CSE 130 Programming Languages Datatypes Ranjit Jhala UC San Diego Recap: ML s Holy Trinity Expressions (Syntax) Exec-time Dynamic Values (Semantics) Compile-time Static Types 1. Programmer enters expression

More information

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

Recap from last time. Programming Languages. CSE 130 : Fall Lecture 3: Data Types. Put it together: a filter function CSE 130 : Fall 2011 Recap from last time Programming Languages Lecture 3: Data Types Ranjit Jhala UC San Diego 1 2 A shorthand for function binding Put it together: a filter function # let neg = fun f

More information

cs242 Kathleen Fisher Reading: Concepts in Programming Languages, Chapter 6 Thanks to John Mitchell for some of these slides.

cs242 Kathleen Fisher Reading: Concepts in Programming Languages, Chapter 6 Thanks to John Mitchell for some of these slides. cs242 Kathleen Fisher Reading: Concepts in Programming Languages, Chapter 6 Thanks to John Mitchell for some of these slides. We are looking for homework graders. If you are interested, send mail to cs242cs.stanford.edu

More information

Project 3 Due October 21, 2015, 11:59:59pm

Project 3 Due October 21, 2015, 11:59:59pm Project 3 Due October 21, 2015, 11:59:59pm 1 Introduction In this project, you will implement RubeVM, a virtual machine for a simple bytecode language. Later in the semester, you will compile Rube (a simplified

More information

Formal Semantics. Prof. Clarkson Fall Today s music: Down to Earth by Peter Gabriel from the WALL-E soundtrack

Formal Semantics. Prof. Clarkson Fall Today s music: Down to Earth by Peter Gabriel from the WALL-E soundtrack Formal Semantics Prof. Clarkson Fall 2015 Today s music: Down to Earth by Peter Gabriel from the WALL-E soundtrack Review Previously in 3110: simple interpreter for expression language: abstract syntax

More information

Programming Language Features. CMSC 330: Organization of Programming Languages. Turing Completeness. Turing Machine.

Programming Language Features. CMSC 330: Organization of Programming Languages. Turing Completeness. Turing Machine. CMSC 330: Organization of Programming Languages Lambda Calculus Programming Language Features Many features exist simply for convenience Multi-argument functions foo ( a, b, c ) Ø Use currying or tuples

More information

CMSC 330: Organization of Programming Languages

CMSC 330: Organization of Programming Languages CMSC 330: Organization of Programming Languages Lambda Calculus CMSC 330 1 Programming Language Features Many features exist simply for convenience Multi-argument functions foo ( a, b, c ) Ø Use currying

More information

PROFESSOR: Last time, we took a look at an explicit control evaluator for Lisp, and that bridged the gap between

PROFESSOR: Last time, we took a look at an explicit control evaluator for Lisp, and that bridged the gap between MITOCW Lecture 10A [MUSIC PLAYING] PROFESSOR: Last time, we took a look at an explicit control evaluator for Lisp, and that bridged the gap between all these high-level languages like Lisp and the query

More information

Lambda Calculus and Type Inference

Lambda Calculus and Type Inference Lambda Calculus and Type Inference Björn Lisper Dept. of Computer Science and Engineering Mälardalen University bjorn.lisper@mdh.se http://www.idt.mdh.se/ blr/ October 13, 2004 Lambda Calculus and Type

More information

Recap: ML s Holy Trinity

Recap: ML s Holy Trinity Recap: ML s Holy Trinity Expressions (Syntax) Exec-time Dynamic Values (Semantics) Compile-time Static Types 1. Programmer enters expression 2. ML checks if expression is well-typed Using a precise set

More information

Fall Lecture 13 Thursday, October 11

Fall Lecture 13 Thursday, October 11 15-150 Fall 2018 Lecture 13 Thursday, October 11 n queens One s favorite ipod app n queens Queens attack on row, column, or diagonal Task: put n queens safely on an n-by-n board British Museum algorithm

More information

Region-Based Memory Management in Cyclone

Region-Based Memory Management in Cyclone Region-Based Memory Management in Cyclone Dan Grossman Cornell University June 2002 Joint work with: Greg Morrisett, Trevor Jim (AT&T), Michael Hicks, James Cheney, Yanling Wang Cyclone A safe C-level

More information

Programming Languages Third Edition

Programming Languages Third Edition Programming Languages Third Edition Chapter 12 Formal Semantics Objectives Become familiar with a sample small language for the purpose of semantic specification Understand operational semantics Understand

More information

Type Theory meets Effects. Greg Morrisett

Type Theory meets Effects. Greg Morrisett Type Theory meets Effects Greg Morrisett A Famous Phrase: Well typed programs won t go wrong. 1. Describe abstract machine: M ::= 2. Give transition relation: M 1 M 2

More information

COSE212: Programming Languages. Lecture 3 Functional Programming in OCaml

COSE212: Programming Languages. Lecture 3 Functional Programming in OCaml COSE212: Programming Languages Lecture 3 Functional Programming in OCaml Hakjoo Oh 2017 Fall Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 1 / 44 Why learn ML? Learning ML is a good way of

More information