tweak calc improvements
[lambda.git] / advanced_topics / calculator_improvements.mdwn
index e22afb1..cbf4c89 100644 (file)
@@ -120,7 +120,7 @@ We can begin with our language:
                | Lambda of (char * term)
                | Apply of (term * term);;
 
-Next, we need to expand our stock of `expressed_value`s to include function values as well. How should we think of these? We've several times mentioned the issue of how to handle free variables in a function's body, like the `x` in `lambda y -> y + x`. We'll follow the usual functional programming standard for these (known as "lexical scoping"), which keeps track of what value `x` has in the function expression's lexical environment. That shouldn't get shadowed by any different value `x` may have when the function value is later applied. So:
+Next, we need to expand our stock of `expressed_value`s to include function values as well. How should we think of these? We've several times mentioned the issue of how to handle free variables in a function's body, like the `x` in `lambda y -> y + x`. We'll follow the usual functional programming standard for these (known as "lexical scoping"), which keeps track of what value `x` has in the function declaration's lexical environment. That shouldn't get shadowed by any different value `x` may have when the function value is later applied. So:
 
        let x = 1 in let f = lambda y -> y + x in let x = 2 in apply f 2
 
@@ -145,9 +145,9 @@ Now our evaluation function needs two further clauses to interpret the two new e
        ...
        | Lambda(arg_var, t1) -> Closure (arg_var, t1, g)
        | Apply(t1, t2) ->
-               let value2 = eval t2 g
                (* we don't handle cases where t1 doesn't evaluate to a function value *)
-               in let Closure (arg_var, body, savedg) = eval t1 g
+               let Closure (arg_var, body, savedg) = eval t1 g
+               in let value2 = eval t2 g
                (* evaluate body under savedg, except with arg_var bound to value2 *)
                in let savedg' = (arg_var, value2) :: savedg
                in eval body savedg';;
@@ -157,7 +157,7 @@ Now our evaluation function needs two further clauses to interpret the two new e
 
 There are different ways to include recursion in our calculator. First, let's imagine our language expanded like this:
 
-       let x = 1 in letrec f = lambda y -> if iszero y then x else y * f (y - 1) in f 3
+       let x = 1 in letrec f = lambda y -> if iszero y then x else y * apply f (y - 1) in apply f 3
 
 where the AST would be:
 
@@ -276,9 +276,9 @@ Since we're not permitting ourselves OCaml's ability to recursively define cycli
        ...
        | Lambda(arg_var, t1) -> Closure (arg_var, t1, g)
        | Apply(t1, t2) ->
-               let value2 = eval t2 g
                (* we don't handle cases where t1 doesn't evaluate to a function value *)
-               in let Closure (arg_var, body, savedg) = eval t1 g
+               let Closure (arg_var, body, savedg) = eval t1 g
+               in let value2 = eval t2 g
                (* evaluate body under savedg, except with arg_var bound to Nonrecursive value2 *)
                in let savedg' = (arg_var, Nonrecursive value2) :: savedg
                in eval body savedg'