1: The program will print "The factorial of 3 is 6". No other assumptions are really needed, however, if the student mentions them that is fine too (as long as they are correct/reasonable). 2: The student needs to show that s/he is able to draw activation records on the stack, with static and dynamic links. Recursive calls should make for a new block (unless something specific is mentioned about tail call optimizations). The input needs to be correctly sent "down" the stack as a parameter to the function calls, and space needs to be allocated for this in the block. 3: Even though it has been mentioned in the task that this language has static scope, exception handlers are typically implemented utilizing dynamic scope, with control flow following the dynamic links on the stack. A mention of these facts is expected. 4: For each activation record that is allocated on the stack, the runtime system will move the environment pointer. In the same operation, one could keep track of stack size. A mention of how different activation records take up a varying amount of stack space should be included for full points. Other approaches such as calculating total stack size in some other way, or counting recursive depth is also alright - however, the solution should be general, and not specific to the example program. 5: The main essence of this question is to demonstrate that the candidate knows how to draw function pointers in the form of closures, as a pair with one pointer going to the environment in which the closure was defined, and another going to the code (living elsewhere in memory). Furthermore, the function is passed as a parameter to subsequent calls, and this needs to be drawn correctly. Note: the task may have been a bit confusing as the signatures for factorial and the subsequent calls don't match up - parameters are left out for some of the calls. Since this is not the main point of the exercise, drawings that ignore this, as well as drawings that consider these missing parameters null references (as mentioned in class discussions), are both OK, as long as the stack is correctly drawn, including closure(s) and function parameter(s). 6: The discussion should include at least something about the difficulties involved with typing checking such constructs, and the need to perform a dynamic lookup at runtime for this to work. The program could work as expected, but well-argued opinions to the contrary are also OK - the important point here being that the student demonstrates an understanding of the concepts and tradeoffs involved in the question. 7 PL-1: Draw or describe the tree resulting from evaluation. Explanation must show repeated search for rule matches with successful/failing matches and the single result found. 8 PL unification: Apply Martelli-Montanari algorithm from textbook. Correct/Incorrect. Partial points for partial substitutions. 9 PL Tree: Base case for leaves; recursive case, either simple or with accumulator; correct use of math with ˇ°ISˇ±-predicate to calculate result. 10 makeDuplicates: Possible options for higher-order: through fold or mapping x to [x,x] and subsequent flattening. Partial points for non-higher-order solution with base case/recursive case. Minor deductions for type-errors or other mistakes in flattening etc. 11 SML tail recursion: 1) Can be solved with or without introducing an accumulator argument, since 2nd argument can be used directly. Outer ˇ°oper vˇ± moved into recursive call, e.g. ˇ°mogrify oper (oper v l) rˇ±. Correct construction of wrapper if required. 2) Short explanation (behaves like foldr vs. foldl); no deductions if effect is correctly described but without referring to associativity. 12 SML Tre: 1. Trivial, with base case/recursive case. 2. ˇ°Plainˇ± recursive solution must correctly take into account repeated counting of prefix. Slightly better alternative: recursive calls should pass current distance from root in additional argument. 3. Higher-order solution: helper-function with identity for leaves and ideally parametrized operation used to fold subtree-results. Recursive tree-traversal with helper function. In other words, several opportunities to use higher-order: either in helper by providing operation or using fold on sub-results, or in wrappers by calling tree traversal with different helpers or desired arithmetic operation. 13 Type Inference: Must show parse tree with right structure and right abstraction/application nodes (3x abstraction, 2x application). Corresponding derivation of equations with necessary introduction of required intermediate type variables. Correct use of textbook algorithm for type inference; correct type of root node inferred. Partial points if algorithm correctly executed on wrong graph/wrong equations/ˇ­