You must complete this assignment with a partner. You and your partner should each understand the answers to both problems, so don't just do one each.
We have discussed how the definition of substitution results in an inefficient operator: in the worst case, it can take time at least quadratic in the size of the program (where we can define the program size as the number of nodes in the abstract syntax tree). We talked about deferring substitution using a cache. However, as we discussed in class, implementing the cache using a simple stack of bindings doesn't seem very much more efficient.
Answer the following two questions.
The program
{with {x 4} {with {f {fun {y} {+ x y}}} {with {x 5} {f 10}}}}
should evaluate to 14 by static scoping. Evaluating x
in the
environment at the point of invoking f
, however, yields a value of
15 for the program. Ben Bitdiddle, a sharp if eccentric student, points out
that we can still use the dynamic environment, so long as we take the oldest
value of x
in the environment rather than the newest and for this
example, he’s right!
Is Ben right in general? If so, justify. If not, provide a counterexample program and explain why Ben’s evaluation strategy would produce the wrong answer. (A bonus point for explaining why Ben’s way of thinking about environments is conceptually wrong, irrespective of whether or not it produces the right answer.)