(* evaluate expr2 using original assignment function and new store *)
in eval expr2 g s''
-Note: Chris uses this kind of machinery on the third page of the Nov 22 handout. Except he implements `Let` the way we here implement `Change`. And he adds an implementation of `Alias` (see below). Some minor differences: on his handout (and following Groenendijk, Stockhof and Veltman), he uses `r` and `g` where we use `g` and `s` respectively. Also, he implements his `r` with a function from `char` to `int`, instead of a `(char * int) list`, as we do here. It should be obvious how to translate between these. His implementation requires that variables always already have an associated peg. So that when we call `Let(c, expr1, expr2)` for the first time with `c`, there's a peg whose value is to be updated. That's easier to ensure when you implement the assignment as a function than as a `(char * int) list`.
+Note: Chris uses this kind of machinery on the third page of the Nov 22 handout. Except he implements `Let` the way we here implement `Change`. And he adds an implementation of `Alias` (see below). Some minor differences: on his handout (and following Groenendijk, Stokhof and Veltman), he uses `r` and `g` where we use `g` and `s` respectively. Also, he implements his `r` with a function from `char` to `int`, instead of a `(char * int) list`, as we do here. It should be obvious how to translate between these. His implementation requires that variables always already have an associated peg. So that when we call `Let(c, expr1, expr2)` for the first time with `c`, there's a peg whose value is to be updated. That's easier to ensure when you implement the assignment as a function than as a `(char * int) list`.
##How to implement mutation with a State monad##
(* alternatively, an env could be implemented as type char -> int *)
type 'a reader = env -> 'a;;
- let unit_reader (value : 'a) : 'a reader =
+ let reader_unit (value : 'a) : 'a reader =
fun e -> value;;
- let bind_reader (u : 'a reader) (f : 'a -> 'b reader) : 'b reader =
+ let reader_bind (u : 'a reader) (f : 'a -> 'b reader) : 'b reader =
fun e -> let a = u e
in let u' = f a
in u' e;;
(* this corresponds to having only a single mutable variable *)
type 'a state = store -> ('a, store);;
- let unit_state (value : 'a) : 'a state =
+ let state_unit (value : 'a) : 'a state =
fun s -> (value, s);;
- let bind_state (u : 'a state) (f : 'a -> 'b state) : 'b state =
+ let state_bind (u : 'a state) (f : 'a -> 'b state) : 'b state =
fun s -> let (a, s') = u s
in let u' = f a
in u' s';;
in computation initial_store;;
+* See also our [[State Monad Tutorial]].
+
##Aliasing or Passing by reference##
In point 7 of the Rosetta Stone discussion, the contrast between call-by-name and call-by-value evaluation order appears (though we don't yet call it that). We'll be discussing that more in coming weeks. In the [[damn]] example, continuations and other kinds of side-effects (namely, printing) make an appearance. These too will be center-stage in coming weeks.
+* Now would also be a good time to read [Calculator Improvements](/week10). This reviews the different systems discussed above, as well as other capabilities we can add to the calculators introduced in [week7](/reader_monad_for_variable_binding). We will be building off of that in coming weeks.
##Offsite Reading##