Except, this isn't quite right. It's almost what we want, but not exactly. Can you see the flaw?
-The flaw is this: inside `new_closure`, what is `'f;` bound to? It's bound by `savedg'` to `orig_closure`, which in turn leaves `'f'` free (or bound to whatever existing value it had according to `savedg`). This isn't what we want. It'll break if we need to make applications of `Variable 'f'` which recurse more than once.
+The flaw is this: inside `new_closure`, what is `'f'` bound to? It's bound by `savedg'` to `orig_closure`, which in turn leaves `'f'` free (or bound to whatever existing value it had according to `savedg`). This isn't what we want. It'll break if we need to make applications of `Variable 'f'` which recurse more than once.
What we really want is for `'f'` to be bound to `new_closure`, something like this:
| Let (var_to_bind, t1, t2) ->
let value1 = eval t1 g
- in let g' = fun var -> if var = var_to_bind value1 else g var
+ in let g' = fun var -> if var = var_to_bind then value1 else g var
in eval t2 g'
...
| Letrec (var_to_bind, t1, t2) ->
let Closure (arg_var, body, savedg) = eval t1 g
- in let rec savedg' = fun var -> if var = var_to_bind Closure (arg_var, body, savedg') else savedg var
+ in let rec savedg' = fun var -> if var = var_to_bind then Closure (arg_var, body, savedg') else savedg var
in let g' = fun var -> if var = var_to_bind then Closure (arg_var, body, savedg') else g var
in eval t2 g';;