What we've studied since Mid-Term 1 ----------------------------------- * Assignment - expressed versus denoted values - interaction with lexical scope * Calling conventions - call-by-value - call-by-reference - call-by-name - call-by-need * Types and type inference Exam Content ------------ In-class, open-book, open-notes. The exam might... ... ask you to compute the value of a program using assignment, possibly with call-by-reference arguments. Show the values of the following expressions in the book language with assignment, sequencing, and both call-by-value and call-by-reference arguments: let x = 0 in let f = proc(y) set x = +(x, y) g = proc(y) { set y = +(y, x) ; y } in { (g 2) ; { (f 3) ; (g 4) } } Result: 7 let f = proc(x) { set x = 1 ; x } in let y = 5 in { (f y) ; y } Result: 5 let f = proc(&x) { set x = 1 ; x } in let y = 5 in { (f y) ; y } Result: 1 let f = proc(&x) { set x = x + 1 ; x } let g = proc(&z) +((f z), (f z)) in let y = 5 in (g y) Result: 13 let f = proc(x) { set x = x + 1 ; x } let g = proc(&z) +((f z), (f z)) in let y = 5 in (g y) Result: 12 let f = proc(&x) { set x = x + 1 ; x } let g = proc(z) +((f z), (f z)) in let y = 5 in (g y) Result: 13 ... ask you to compute the value of a program using call-by-value, call-by-name, or call-by-need. Given then expression let x = 0 f = proc(y) set y=+(y,y) in let z = { set x=+(x,1) ; x } in { (f z) ; z } What does the expression produce in the following configurations of the interpreter? 1. All procedure arguments are call-by-value. Result: 1. Right-hand side of the `z' binding increments x once and sets z's result once and for all. 2. All procedure arguments and let bindings are call-by-name. Result: 3. z is used three times, so it's value is incremented three times. 3. All procedure arguments and let bindings are call-by-need. Result: 1. z is used three times, but its value is computed once and for all on the first use. ... ask you to find and prove the type of an expression. Find and prove the type of the following expression: proc(int x)proc((int -> bool) b)if (b x) then x else 10 The type is (int -> ((int -> bool) -> int)). Here is the proof: E1 |- b : (int -> bool) E1 |- x : int -------------------------------------- E1 |- (b x) : bool E1 |- x : int E1 |- 10 : int --------------------------------------------------------------------- E1 = { x : int, b : (int -> bool) } |- if (b x) then x else 10 : int --------------------------------------------------------------------- {x : int} |- proc((int -> bool) b)if (b x) then x else 10 : ((int -> bool) -> int) --------------------------------------------------------------------- {} |- proc(int x)proc((int -> bool) b)if (b x) then x else 10 : (int -> ((int -> bool) -> int)) ... ask you to infer a type expression so that a larger expression has a type. What must T_1 and T_2 be in the following expression, so that it has a type? proc(T_2 x)proc(T_1 b)if (b x) then x else 10 T_2 = int T_1 = (int -> bool) T_2 is int because x must have the same type as 10. T_1 is (int -> bool) because b is applied to x, x has type int, and the application result is used as a test result. ... ask you to understand an untyped program and translate it to a typed program using `cases'. The following program is implemented in the language of HW 5, but without using the fancy tree processing of + and -: let count = proc(a) let f = car(a) t = car(cdr(a)) l = cdr(cdr(a)) in if iscons(l) then +(if (t car(l)) then 1 else 0, (f cons(f, cons(t, cdr(l))))) else 0 in (count cons(count, cons(proc(x)-(x,2), cons(1,cons(2,cons(3, 0)))))) What does it do, and how can it be translated to a typed language? The `count' function is written without letrec and without multi-argument functions, but it corresponds to a recursive function that takes two arguments: a test function and a 0-terminated list. The result is the number of items in the list for which the test function produces a non-zero value. Here is a statically typed implementation using the language of HW 8: numlist = (cons num numlist) or (zeroterminator) in letrec num count((num -> num) t, numlist l) = cases numlist l of [(cons n l) +(ifzero (t n) 0 1, (count t l))] [(zeroterminator) 0] in (count proc(num x)-(x,2) (cons 1 (cons 2 (cons 3 (zeroterminator))))) The exact syntax doesn't matter. The key points are the translation of (some) `cons'es into uses of a typed constrcutor, and the use of `cases' to distinguish cons cells from the zero terminator.