tweak calc improvements
authorJim Pryor <profjim@jimpryor.net>
Fri, 26 Nov 2010 12:52:12 +0000 (07:52 -0500)
committerJim Pryor <profjim@jimpryor.net>
Fri, 26 Nov 2010 12:52:12 +0000 (07:52 -0500)
Signed-off-by: Jim Pryor <profjim@jimpryor.net>
advanced_topics/calculator_improvements.mdwn

index 541e695..7576b22 100644 (file)
@@ -661,6 +661,45 @@ The complete code is available [here](/code/calculator/calc6.ml).
 
 ##Adding Aliasing and Passing by Reference##
 
 
 ##Adding Aliasing and Passing by Reference##
 
+Next we'll add aliasing as described at the end of [[week9]]. We'll also add the ability to pass (implicit) reference cells as arguments to a function, which lets changes made within the function body to be effective in the outside environment. When we discussed this in [[week9]], we proposed a different syntactic form for the function values that get called in this way. Instead of:
+
+       let f = lambda (y) -> ...
+       ...
+       in f x
+
+one would write:
+
+       let f = lambda (alias y) -> ...
+       ...
+       in f x
+
+Real programming languages that have this ability, such as C++, do something analagous. Here the function is declared so that *all* of its applications are expected to alias the supplied argument. You can always work around that in a particular case, though, like this:
+
+       let f = lambda (alias y) -> ...
+       ...
+       in let y = x ; creates new (implicit) reference cell with x's value
+       in f y
+
+In our present framework, it will be easier to do things differently. We will
+introduce a new syntactic forms at the location where a function value is
+applied, rather than in the function's declaration. So we will say instead:
+
+       Let ('f',
+               Lambda ('y', ...),
+               ...
+               Apply(Variable 'f', Variable 'x')...)
+
+for the familiar, passing-by-value behavior, and:
+
+       Let ('f',
+               Lambda ('y', ...),
+               ...
+               Applyalias(Variable 'f', 'x')...)
+
+for the proposed new, passing-by-reference behavior. (Besides being easier to implement here, this strategy also has the advantage of more closely aligning with the formal system Jim discusses in his "Hyper-evaluativity" paper.) Note that the second parameter to the `Applyalias` form is just `'x'`, not `Variable 'x'`. This is because (1) only variables are acceptable there, not arbitrary expressions, and (2) we don't need at that point to compute the variable's present value.
+
+Here is our expanded language:
+
        type term =
          Intconstant of int
        | Multiplication of (term * term)
        type term =
          Intconstant of int
        | Multiplication of (term * term)
@@ -679,6 +718,8 @@ The complete code is available [here](/code/calculator/calc6.ml).
        | Applyalias of (term * char)
        ;;
  
        | Applyalias of (term * char)
        ;;
  
+The definitions of `index`, `bound_value`, `assignment`, `expressed_value`, and `store` can remain as they were in the implementation of implicit-style mutation. Here are the changes to our evaluation function:
+
        let rec eval (t : term) (g : assignment) (s : store) = match t with
        ...
        | Alias (var_to_bind, orig_var, t3) ->
        let rec eval (t : term) (g : assignment) (s : store) = match t with
        ...
        | Alias (var_to_bind, orig_var, t3) ->