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.