# Assignment 6 (week 7) ## Evaluation order in Combinatory Logic 1. Give a term that the lazy evaluators (either the Haskell evaluator, or the lazy version of the OCaml evaluator) do not evaluate all the way to a normal form, i.e., that contains a redex somewhere inside of it after it has been reduced. 2. One of the [[criteria we established for classifying reduction strategies| topics/week3_evaluation_order]] strategies is whether they reduce subexpressions hidden under lambdas. That is, for a term like `(\x y. x z) (\x. x)`, do we reduce to `\y.(\x.x) z` and stop, or do we reduce further to `\y.z`? Explain what the corresponding question would be for CL. Using either the OCaml CL evaluator or the Haskell evaluator developed in the wiki notes, prove that the evaluator does reduce expressions inside of "functional" CL expressions. Then provide a modified evaluator that does not perform reductions in those positions. 3. In the previous homework, one of the techniques for controlling evaluation order was wrapping expressions in a `let`: `let x = blah in foo`, you could be sure that `blah` would be evaluated by the time the interpreter considered `foo` (unless you did some fancy footwork with thunks). That suggests the following way to try to arrive at eager evaluation in our Haskell evaluator for CL: reduce4 t = case t of I -> I K -> K S -> S FA a b -> let b' = reduce4 b in let a' = reduce4 a in let t' = FA a' b' in if (is_redex t') then reduce4 (reduce_one_step t') else t' Will this work? That is, will `reduce4 (FA (FA K I) skomega)` go into an infinite loop? Run the code to find out, if you must, but write down your guess (and your rationale) first.