X-Git-Url: http://lambda.jimpryor.net/git/gitweb.cgi?p=lambda.git;a=blobdiff_plain;f=week9.mdwn;h=1992e207563a97504dfbbc1cbc154d0929d678d2;hp=a738524923249461788335292199116dedb75c29;hb=945835525c1a4f9d8210693af0b60ecf957ba8be;hpb=a07a7e1719e637449177695d4f703d656b8e5ccb diff --git a/week9.mdwn b/week9.mdwn index a7385249..1992e207 100644 --- a/week9.mdwn +++ b/week9.mdwn @@ -429,7 +429,7 @@ Here's how to implement these. We'll suppose that our assignment function is lis (* 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## @@ -446,9 +446,9 @@ Here's the implementation of the State monad, together with an implementation of (* 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;; @@ -458,9 +458,9 @@ Here's the implementation of the State monad, together with an implementation of (* 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';; @@ -503,6 +503,8 @@ To get the whole process started, the complex computation so defined will need t in computation initial_store;; +* See also our [[State Monad Tutorial]]. + ##Aliasing or Passing by reference## @@ -628,10 +630,10 @@ Programming languages tend to provide a bunch of mutation-related capabilities a Because of the particular way the numerical identity predicates are implemented in all of these languages, it doesn't quite match our conceptual expectations. For instance, For instance, if `ycell` is a reference cell, then `ref !ycell` will always be a numerically distinct reference cell containing the same value. We get this pattern of comparisons in OCaml: ycell == ycell - ycell != ref !ycell (* these aren't numerically identical *) + ycell != ref !ycell (* true, these aren't numerically identical *) ycell = ycell - ycell = ref !ycell (* they are qualitatively indiscernible *) + ycell = ref !ycell (* true, they are qualitatively indiscernible *) But now what about? @@ -751,6 +753,7 @@ Programming languages tend to provide a bunch of mutation-related capabilities a 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##