X-Git-Url: http://lambda.jimpryor.net/git/gitweb.cgi?a=blobdiff_plain;f=advanced_topics%2Fcalculator_improvements.mdwn;h=d3beef126002eea1d63aeb8b753090a21713a682;hb=a9b6b232eb91e8db74289853cefcf50c77edf3f7;hp=541e6958e1c1bb54783f5691e886aa9801c93ce7;hpb=afae1eb5d1dc7633dd5ac8f0e2535c22cd9cfaea;p=lambda.git diff --git a/advanced_topics/calculator_improvements.mdwn b/advanced_topics/calculator_improvements.mdwn index 541e6958..d3beef12 100644 --- a/advanced_topics/calculator_improvements.mdwn +++ b/advanced_topics/calculator_improvements.mdwn @@ -661,6 +661,45 @@ The complete code is available [here](/code/calculator/calc6.ml). ##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 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 form at the location where a function value is +applied, rather than in the function's declaration. We say: + + Let ('f', + Lambda ('y', ...), + ... + Apply(Variable 'f', Variable 'x')...) + +for the familiar, passing-by-value behavior, and will instead say: + + 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) @@ -679,6 +718,8 @@ The complete code is available [here](/code/calculator/calc6.ml). | 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) ->