X-Git-Url: http://lambda.jimpryor.net/git/gitweb.cgi?p=lambda.git;a=blobdiff_plain;f=week9.mdwn;h=dac311cb89dd3763ff28c812a73b4ed41dbe3b40;hp=913e4bf75d91269a951092ed48e2540f8a35922d;hb=5d3d0a72ea4e8f1d23816d851fed8027ce768864;hpb=279ca93246cad2d4ad11ac33887df3bb9cc97759 diff --git a/week9.mdwn b/week9.mdwn index 913e4bf7..dac311cb 100644 --- a/week9.mdwn +++ b/week9.mdwn @@ -100,7 +100,13 @@ Scheme is similar. There are various sorts of reference cells available in Schem (set-box! ycell 3) (+ x (unbox ycell))) -(C has explicit-style mutable variables, too, which it calls *pointers*. But simple variables in C are already mutable, in the implicit style.) +C has explicit-style mutable variables, too, which it calls *pointers*. But simple variables in C are already mutable, in the implicit style. Scheme also has both styles of mutation. In addition to the explicit boxes, Scheme also lets you mutate unboxed variables: + + (begin + (define x 1) + (set! x 2) + x) + ; evaluates to 2 When dealing with explicit-style mutation, there's a difference between the types and values of `ycell` and `!ycell` (or in Scheme, `(unbox ycell)`). The former has the type `int ref`: the variable `ycell` is assigned a reference cell that contains an `int`. The latter has the type `int`, and has whatever value is now stored in the relevant reference cell. In an implicit-style framework though, we only have the resources to refer to the contents of the relevant reference cell. `y` in fragment [G] or the C snippet above has the type `int`, and only ever evaluates to `int` values. @@ -320,7 +326,7 @@ Similarly: Let's consider how to interpet our new syntactic forms `newref`, `deref`, and `setref`: -1. \[[newref starting_val]] should allocate a new reference cell in the store and insert `starting_val` into that cell. It should return some "key" or "index" or "pointer" to the newly created reference cell, so that we can do things like: +1. When `expr` evaluates to `starting_val`, **newref expr** should allocate a new reference cell in the store and insert `starting_val` into that cell. It should return some "key" or "index" or "pointer" to the newly created reference cell, so that we can do things like: let ycell = newref 1 in ... @@ -345,7 +351,7 @@ Let's consider how to interpet our new syntactic forms `newref`, `deref`, and `s in (Index new_index, s'') ... -2. When `expr` evaluates to a `store_index`, then `deref expr` should evaluate to whatever value is at that index in the current store. (If `expr` evaluates to a value of another type, `deref expr` is undefined.) In this operation, we don't change the store at all; we're just reading from it. So we'll return the same store back unchanged (assuming it wasn't changed during the evaluation of `expr`). +2. When `expr` evaluates to a `store_index`, then **deref expr** should evaluate to whatever value is at that index in the current store. (If `expr` evaluates to a value of another type, `deref expr` is undefined.) In this operation, we don't change the store at all; we're just reading from it. So we'll return the same store back unchanged (assuming it wasn't changed during the evaluation of `expr`). let rec eval expression g s = match expression with @@ -356,7 +362,7 @@ Let's consider how to interpet our new syntactic forms `newref`, `deref`, and `s in (List.nth s' n, s') ... -3. When `expr1` evaluates to a `store_index` and `expr2` evaluates to an `int`, then `setref expr1 expr2` should have the effect of changing the store so that the reference cell at that index now contains that `int`. We have to make a decision about what value the `setref ...` call should itself evaluate to; OCaml makes this `()` but other choices are also possible. Here I'll just suppose we've got some appropriate value in the variable `dummy`. +3. When `expr1` evaluates to a `store_index` and `expr2` evaluates to an `int`, then **setref expr1 expr2** should have the effect of changing the store so that the reference cell at that index now contains that `int`. We have to make a decision about what value the `setref ...` call should itself evaluate to; OCaml makes this `()` but other choices are also possible. Here I'll just suppose we've got some appropriate value in the variable `dummy`. let rec eval expression g s = match expression with