Practice Midterm Feb 4, 2014 (with some solutions) The questions in this practice midterm are meant to be representative of the kind of questions that will be found in the actual midterm on Feb 11, 2014. During that midterm, each student will be allowed one (8.5 x 11.0 inch) page of notes. SHORT ANSWER, 5 points each. 1) Explain the differences between a value-model of variables and a reference model of variables 2) In a pseudo code language with call-by-reference, give an example of aliasing. Be sure and clearly state what is aliased. (def f (x y z) (+ x (* y (:= z y)))) (global a 45) In the call of (@ f a 5 a) in the body of "f" the formal parameters "x" and "z" are aliases for the global variable "a" 3) What advantages does heap based allocation have over stack based allocation. Explain what language feature might make use of those advantages. 4) What is a closure? What language features do closures enable? A closure is an implementation for a function. It pairs the enviroment of definition of the function along with the code that executes the functions body. In our interpreter this means a triple (Env Addr,[FName],Exp). Closures enable static scoping and first class functions. 5) Calling conventions are often broken up into several parts. What are the names commonly given to these parts. What are typical roles of each of the parts? 6) Compare eager and lazy semantics. Discuss uses, semantics, advantages etc. Name a language that uses each kind of semantics CODE INSPECTION. 5 points each. Study the snippets of code for an E3 like language on page 2 of this exam. These snippets of code come directly from HW3.hs, or are simple modifications of that code. You must study the code and then answer the questions. I might have changed the semantics of E3 in subtle ways. 7) Does the predicate (ispair x) return an error if x is not a pair? No it returns 0, which stands for False. 8) What values does an empty block return. It returns 1 9) In what order are the arguments to functions evaluated? arguments to functions are evaluated from left-to-right 10) What value does this while statement return. Assume both "x" and "y" are initialized to 0. (while (<= x 10) (block (:= x (+ x 1)) (:= y x)) It returns 10, in fact all while statements return 10. 11) Assuming "x" is in scope, what value does (:= x 9) return? It returns 1, all assignments return 1, In this language they are run only for the "effect" of changing the value of the variable. 12) In what order are pairs evaluated? right to left. STATIC SCOPING IN BLOCK STRUCTURED LANGUAGES. 15 points 13) In a block structured language where each block may introduce statically scoped local variables, and where blocks may be nested, sketch (draw a picture) of how these statically scoped variables might be stack allocated. First create a pseudo code example with 3 nested blocks, and at least 6 variables. Then sketch the stack when the code is executing inside the most deeply nested block. Clearly indicate activation frames, frame pointers, and the location of each variable. Discuss how the memory for a variable is located. CODE SNIPPETS FOR QUESTIONS 6-12 interpE funs vars state exp = run state exp where run state (Int n) = return(IntV n,state) run state (Asgn v e ) = do { (val,state2) <- interpE funs vars state e ; case lookUp vars v of Found addr -> return(IntV 1,stateStore addr val state2) NotFound -> error ("\nUnknown variable: "++v++" in assignment.") } run state (term@(At f args)) = case lookUp funs f of NotFound -> error ("\nUnknown function: "++f++" in function call.") Found (vars2,formals,body) -> do { when (length args /= length formals) (error ("\nWrong number of args to: "++f++" in: "++show term)) ; (vs,state2) <- interpList funs vars state args ; let (pairs,state3) = bind formals vs state2 ; (v,state4) <- interpE funs (push pairs vars2) state3 body ; return(v,state4) } run state (While tst body)= while state where while state = do { (v,state2) <- interpE funs vars state tst ; test "while" v (do { (_,state3) <- interpE funs vars state2 body ; while state3}) (return(IntV 10,state2))} run state (Block es) = do { let last [] = (IntV 1) last [x] = x last (x:xs) = last xs ; (vs,state2) <- interpList funs vars state es ; return(last vs,state2)} run state (Add x y) = do { (v1,state1) <- interpE funs vars state x ; (v2,state2) <- interpE funs vars state1 y ; return(numeric state2 "+" (+) v1 v2,state2) } run state (Leq x y) = do { (v1,state1) <- interpE funs vars state x ; (v2,state2) <- interpE funs vars state1 y ; return(numeric state2 "<=" (\ x y -> boolToInt(x <= y)) v1 v2,state2) } run state (Pair x y) = do { (v1,state1) <- interpE funs vars state x ; (v2,state2) <- interpE funs vars state1 y ; let (a2,state4) = alloc v2 state3 (a1,state3) = alloc v1 state2 ; return(PairV a1,state4)} run state (Ispair x) = do { (v1,state1) <- interpE funs vars state x ; case v1 of (PairV _) -> return(IntV(boolToInt True),state1) other -> return(IntV(boolToInt False),state1)} interpList funs vars state [] = return([],state) interpList funs vars state (e:es) = do { (vs,state1) <- interpList funs vars state es ; (v,state2) <- interpE funs vars state1 e ; return(v:vs,state2)} CALLING CONVENTIONS 5 points each Consider the following E3 like language, where individual parameters of a function can have different calling conventions. Below, the first parameter, x, is passed by value, the second parameter, y, is passed by reference, and the third parameter, z, is passed by value return. (fun f ((value x) (reference y) (value-return z)) (block (:= y x) (:= z x) (:= x (+ y z))) For each of the calls to "f" below, state the values of all the variables "a", "b", and "c", after the call executes. Assume that they are all intialized as follows "a"=3, "b"=7, "c"=1, before each call. 14) (@ f a b c) 15) (@ f b b a) 16) (@ f a a a) EXCEPTIONS 10 points In most languages, an exception is caught by the most recent handler along the dynamic chain of call. An obvious way to implement exceptions is as a linked list of handlers. Explain how this list might be used in the following circumstances. 17) When control enters a "try" statement. 18) When a "raise" statement is executed. 19) When a handler doesn't match the current exception. SMALL FUNCTIONAL PROGRAMS in HASKELL 5 points each 20) Write a function, constant, that given a value n (like 5), returns a unary function. This returned function always returns n, regardless of what it is applied to. For example f = constant 7 f 6 --> 7 f 99 --> 7 using anoymous functions: constant n = (\ x -> n) or using currying: constant n x = n or using a local function constant n = let f x = n in f 21) Write the zipWith2 function. It takes a curried binary function, and two lists, and applies the function point wise to each element in the lists. It stops when the end of the shortest list is reached. You may use expliti recursion. For example zipWith2 (\ x y -> x + y) [1,4,5] [4,6] --> [5,10] zipWith2 f [] xs = [] zipWith2 f ys [] = [] zipWith2 f (y:ts) (x:xs) = (f x y):(zipWith2 f ys xs) or zipWith2 f xs ys = case (xs,ys) of ([],_) -> [] (_,[]) -> [] (a:as,b:bs) -> (f a b):(zipWith2 f xs ys) or zipWith2 f xs ys = help xs ys where help [] _ = [] help _ [] = [] help (a:as) (b:bs) = (f a b):(zipWith2 f xs ys)