week9 tweak
[lambda.git] / week7.mdwn
index 2abf10d..abb6cfe 100644 (file)
 [[!toc]]
 
 
-Monads
-------
-
-Start by (re)reading the discussion of monads in the lecture notes for
-week 6 [[Towards Monads]].
-In those notes, we saw a way to separate thinking about error
-conditions (such as trying to divide by zero) from thinking about
-normal arithmetic computations.  We did this by making use of the
-`option` type: in each place where we had something of type `int`, we
-put instead something of type `int option`, which is a sum type
-consisting either of one choice with an `int` payload, or else a `None`
-choice which we interpret as  signaling that something has gone wrong.
-
-The goal was to make normal computing as convenient as possible: when
-we're adding or multiplying, we don't have to worry about generating
-any new errors, so we do want to think about the difference between
-`int`s and `int option`s.  We tried to accomplish this by defining a
-`bind` operator, which enabled us to peel away the `option` husk to get
-at the delicious integer inside.  There was also a homework problem
-which made this even more convenient by mapping any binary operation
-on plain integers into a lifted operation that understands how to deal
-with `int option`s in a sensible way.
+Towards Monads: Safe division
+-----------------------------
+
+[This section used to be near the end of the lecture notes for week 6]
+
+We begin by reasoning about what should happen when someone tries to
+divide by zero.  This will lead us to a general programming technique
+called a *monad*, which we'll see in many guises in the weeks to come.
+
+Integer division presupposes that its second argument
+(the divisor) is not zero, upon pain of presupposition failure.
+Here's what my OCaml interpreter says:
+
+    # 12/0;;
+    Exception: Division_by_zero.
+
+So we want to explicitly allow for the possibility that
+division will return something other than a number.
+We'll use OCaml's `option` type, which works like this:
+
+    # type 'a option = None | Some of 'a;;
+    # None;;
+    - : 'a option = None
+    # Some 3;;
+    - : int option = Some 3
+
+So if a division is normal, we return some number, but if the divisor is
+zero, we return `None`. As a mnemonic aid, we'll append a `'` to the end of our new divide function.
+
+<pre>
+let div' (x:int) (y:int) =
+  match y with
+         0 -> None
+    | _ -> Some (x / y);;
+
+(*
+val div' : int -> int -> int option = fun
+# div' 12 2;;
+- : int option = Some 6
+# div' 12 0;;
+- : int option = None
+# div' (div' 12 2) 3;;
+Characters 4-14:
+  div' (div' 12 2) 3;;
+        ^^^^^^^^^^
+Error: This expression has type int option
+       but an expression was expected of type int
+*)
+</pre>
+
+This starts off well: dividing 12 by 2, no problem; dividing 12 by 0,
+just the behavior we were hoping for.  But we want to be able to use
+the output of the safe-division function as input for further division
+operations.  So we have to jack up the types of the inputs:
+
+<pre>
+let div' (u:int option) (v:int option) =
+  match u with
+         None -> None
+       | Some x -> (match v with
+                                 Some 0 -> None
+                               | Some y -> Some (x / y));;
+
+(*
+val div' : int option -> int option -> int option = <fun>
+# div' (Some 12) (Some 2);;
+- : int option = Some 6
+# div' (Some 12) (Some 0);;
+- : int option = None
+# div' (div' (Some 12) (Some 0)) (Some 3);;
+- : int option = None
+*)
+</pre>
+
+Beautiful, just what we need: now we can try to divide by anything we
+want, without fear that we're going to trigger any system errors.
+
+I prefer to line up the `match` alternatives by using OCaml's
+built-in tuple type:
+
+<pre>
+let div' (u:int option) (v:int option) =
+  match (u, v) with
+         (None, _) -> None
+    | (_, None) -> None
+    | (_, Some 0) -> None
+       | (Some x, Some y) -> Some (x / y);;
+</pre>
+
+So far so good.  But what if we want to combine division with
+other arithmetic operations?  We need to make those other operations
+aware of the possibility that one of their arguments has triggered a
+presupposition failure:
+
+<pre>
+let add' (u:int option) (v:int option) =
+  match (u, v) with
+         (None, _) -> None
+    | (_, None) -> None
+    | (Some x, Some y) -> Some (x + y);;
+
+(*
+val add' : int option -> int option -> int option = <fun>
+# add' (Some 12) (Some 4);;
+- : int option = Some 16
+# add' (div' (Some 12) (Some 0)) (Some 4);;
+- : int option = None
+*)
+</pre>
+
+This works, but is somewhat disappointing: the `add'` operation
+doesn't trigger any presupposition of its own, so it is a shame that
+it needs to be adjusted because someone else might make trouble.
+
+But we can automate the adjustment.  The standard way in OCaml,
+Haskell, etc., is to define a `bind` operator (the name `bind` is not
+well chosen to resonate with linguists, but what can you do). To continue our mnemonic association, we'll put a `'` after the name "bind" as well.
+
+<pre>
+let bind' (u: int option) (f: int -> (int option)) =
+  match u with
+         None -> None
+    | Some x -> f x;;
+
+let add' (u: int option) (v: int option)  =
+  bind' u (fun x -> bind' v (fun y -> Some (x + y)));;
+
+let div' (u: int option) (v: int option) =
+  bind' u (fun x -> bind' v (fun y -> if (0 = y) then None else Some (x / y)));;
+
+(*
+#  div' (div' (Some 12) (Some 2)) (Some 3);;
+- : int option = Some 2
+#  div' (div' (Some 12) (Some 0)) (Some 3);;
+- : int option = None
+# add' (div' (Some 12) (Some 0)) (Some 3);;
+- : int option = None
+*)
+</pre>
+
+Compare the new definitions of `add'` and `div'` closely: the definition
+for `add'` shows what it looks like to equip an ordinary operation to
+survive in dangerous presupposition-filled world.  Note that the new
+definition of `add'` does not need to test whether its arguments are
+None objects or real numbers---those details are hidden inside of the
+`bind'` function.
+
+The definition of `div'` shows exactly what extra needs to be said in
+order to trigger the no-division-by-zero presupposition.
 
 [Linguitics note: Dividing by zero is supposed to feel like a kind of
 presupposition failure.  If we wanted to adapt this approach to
@@ -39,6 +166,29 @@ material that otherwise would trigger a presupposition violation; but,
 not surprisingly, these refinements will require some more
 sophisticated techniques than the super-simple option monad.]
 
+
+Monads in General
+-----------------
+
+We've just seen a way to separate thinking about error conditions
+(such as trying to divide by zero) from thinking about normal
+arithmetic computations.  We did this by making use of the `option`
+type: in each place where we had something of type `int`, we put
+instead something of type `int option`, which is a sum type consisting
+either of one choice with an `int` payload, or else a `None` choice
+which we interpret as signaling that something has gone wrong.
+
+The goal was to make normal computing as convenient as possible: when
+we're adding or multiplying, we don't have to worry about generating
+any new errors, so we would rather not think about the difference
+between `int`s and `int option`s.  We tried to accomplish this by
+defining a `bind` operator, which enabled us to peel away the `option`
+husk to get at the delicious integer inside.  There was also a
+homework problem which made this even more convenient by defining a
+`lift` operator that mapped any binary operation on plain integers
+into a lifted operation that understands how to deal with `int
+option`s in a sensible way.
+
 So what exactly is a monad?  We can consider a monad to be a system
 that provides at least the following three elements:
 
@@ -59,7 +209,12 @@ that provides at least the following three elements:
        discussing earlier (whose value is written `()`). It's also only
        very loosely connected to the "return" keyword in many other
        programming languages like C. But these are the names that the literature
-       uses.
+       uses.  [The rationale for "unit" comes from the monad laws
+       (see below), where the unit function serves as an identity,
+       just like the unit number (i.e., 1) serves as the identity
+       object for multiplication.  The rationale for "return" comes
+       from a misguided desire to resonate with C programmers and
+       other imperative types.]
 
        The unit/return operation is a way of lifting an ordinary object into
        the monadic box you've defined, in the simplest way possible. You can think
@@ -81,7 +236,7 @@ that provides at least the following three elements:
        most straightforward way to lift an ordinary value into a monadic value
        of the monadic type in question.
 
-*      Thirdly, an operation that's often called `bind`. This is another
+*      Thirdly, an operation that's often called `bind`. As we said before, this is another
        unfortunate name: this operation is only very loosely connected to
        what linguists usually mean by "binding." In our option/maybe monad, the
        bind operation is:
@@ -119,6 +274,8 @@ that provides at least the following three elements:
        be defined so as to make sure that the result of `f x` was also
        a singing box. If `f` also wanted to insert a song, you'd have to decide
        whether both songs would be carried through, or only one of them.
+        (Are you beginning to realize how wierd and wonderful monads
+       can be?)
 
        There is no single `bind` function that dictates how this must go.
        For each new monadic type, this has to be worked out in an
@@ -128,17 +285,11 @@ So the "option/maybe monad" consists of the polymorphic `option` type, the
 `unit`/return function, and the `bind` function.
 
 
-A note on notation: Haskell uses the infix operator `>>=` to stand
-for `bind`. Chris really hates that symbol.  Following Wadler, he prefers to
-use an infix five-pointed star &#8902;, or on a keyboard, `*`. Jim on the other hand
-thinks `>>=` is what the literature uses and students won't be able to
-avoid it. Moreover, although &#8902; is OK (though not a convention that's been picked up), overloading the multiplication symbol invites its own confusion
-and Jim feels very uneasy about that. If not `>>=` then we should use
-some other unfamiliar infix symbol (but `>>=` already is such...)
+A note on notation: Haskell uses the infix operator `>>=` to stand for
+`bind`: wherever you see `u >>= f`, that means `bind u f`.
+Wadler uses &#8902;, but that hasn't been widely adopted (unfortunately).
 
-In any case, the course leaders will work this out somehow. In the meantime,
-as you read around, wherever you see `u >>= f`, that means `bind u f`. Also,
-if you ever see this notation:
+Also, if you ever see this notation:
 
        do
                x <- u
@@ -152,9 +303,14 @@ Similarly:
                y <- v
                f x y
 
-is shorthand for `u >>= (\x -> v >>= (\y -> f x y))`, that is, `bind u (fun x
--> bind v (fun y -> f x y))`. Those who did last week's homework may recognize
-this last expression.
+is shorthand for `u >>= (\x -> v >>= (\y -> f x y))`, that is, `bind u
+(fun x -> bind v (fun y -> f x y))`. Those who did last week's
+homework may recognize this last expression.  You can think of the
+notation like this: take the singing box `u` and evaluate it (which
+includes listening to the song).  Take the int contained in the
+singing box (the end result of evaluting `u`) and bind the variable
+`x` to that int.  So `x <- u` means "Sing me up an int, which I'll call
+`x`".
 
 (Note that the above "do" notation comes from Haskell. We're mentioning it here
 because you're likely to see it when reading about monads. It won't work in
@@ -209,64 +365,69 @@ Just like good robots, monads must obey three laws designed to prevent
 them from hurting the people that use them or themselves.
 
 *      **Left identity: unit is a left identity for the bind operation.**
-       That is, for all `f:'a -> 'a m`, where `'a m` is a monadic
-       type, we have `(unit x) * f == f x`.  For instance, `unit` is itself
+       That is, for all `f:'a -> 'b m`, where `'b m` is a monadic
+       type, we have `(unit x) >>= f == f x`.  For instance, `unit` is itself
        a function of type `'a -> 'a m`, so we can use it for `f`:
 
                # let unit x = Some x;;
                val unit : 'a -> 'a option = <fun>
-               # let ( * ) u f = match u with None -> None | Some x -> f x;;
-               val ( * ) : 'a option -> ('a -> 'b option) -> 'b option = <fun>
+               # let ( >>= ) u f = match u with None -> None | Some x -> f x;;
+               val ( >>= ) : 'a option -> ('a -> 'b option) -> 'b option = <fun>
 
        The parentheses is the magic for telling OCaml that the
        function to be defined (in this case, the name of the function
-       is `*`, pronounced "bind") is an infix operator, so we write
-       `u * f` or `( * ) u f` instead of `* u f`. Now:
+       is `>>=`, pronounced "bind") is an infix operator, so we write
+       `u >>= f` or equivalently `( >>= ) u f` instead of `>>= u
+       f`.
 
                # unit 2;;
                - : int option = Some 2
-               # unit 2 * unit;;
+               # unit 2 >>= unit;;
                - : int option = Some 2
 
+       Now, for a less trivial instance of a function from `int`s to `int option`s:
+
                # let divide x y = if 0 = y then None else Some (x/y);;
                val divide : int -> int -> int option = <fun>
                # divide 6 2;;
                - : int option = Some 3
-               # unit 2 * divide 6;;
+               # unit 2 >>= divide 6;;
                - : int option = Some 3
 
                # divide 6 0;;
                - : int option = None
-               # unit 0 * divide 6;;
+               # unit 0 >>= divide 6;;
                - : int option = None
 
 
 *      **Associativity: bind obeys a kind of associativity**. Like this:
 
-               (u * f) * g == u * (fun x -> f x * g)
+               (u >>= f) >>= g == u >>= (fun x -> f x >>= g)
 
-       If you don't understand why the lambda form is necessary (the "fun
-       x" part), you need to look again at the type of `bind`.
+       If you don't understand why the lambda form is necessary (the
+       "fun x -> ..." part), you need to look again at the type of `bind`.
 
-       Some examples of associativity in the option monad:
+       Some examples of associativity in the option monad (bear in
+       mind that in the Ocaml implementation of integer division, 2/3
+       evaluates to zero, throwing away the remainder):
 
-               # Some 3 * unit * unit;; 
+               # Some 3 >>= unit >>= unit;; 
                - : int option = Some 3
-               # Some 3 * (fun x -> unit x * unit);;
+               # Some 3 >>= (fun x -> unit x >>= unit);;
                - : int option = Some 3
 
-               # Some 3 * divide 6 * divide 2;;
+               # Some 3 >>= divide 6 >>= divide 2;;
                - : int option = Some 1
-               # Some 3 * (fun x -> divide 6 x * divide 2);;
+               # Some 3 >>= (fun x -> divide 6 x >>= divide 2);;
                - : int option = Some 1
 
-               # Some 3 * divide 2 * divide 6;;
+               # Some 3 >>= divide 2 >>= divide 6;;
                - : int option = None
-               # Some 3 * (fun x -> divide 2 x * divide 6);;
+               # Some 3 >>= (fun x -> divide 2 x >>= divide 6);;
                - : int option = None
 
 Of course, associativity must hold for *arbitrary* functions of
-type `'a -> 'a m`, where `m` is the monad type.  It's easy to
+type `'a -> 'b m`, where `m` is the monad type.  It's easy to
 convince yourself that the `bind` operation for the option monad
 obeys associativity by dividing the inputs into cases: if `u`
 matches `None`, both computations will result in `None`; if
@@ -276,11 +437,11 @@ computations will again result in `None`; and if the value of
 to `g y`.
 
 *      **Right identity: unit is a right identity for bind.**  That is, 
-       `u * unit == u` for all monad objects `u`.  For instance,
+       `u >>= unit == u` for all monad objects `u`.  For instance,
 
-               # Some 3 * unit;;
+               # Some 3 >>= unit;;
                - : int option = Some 3
-               # None * unit;;
+               # None >>= unit;;
                - : 'a option = None
 
 
@@ -290,41 +451,38 @@ More details about monads
 If you studied algebra, you'll remember that a *monoid* is an
 associative operation with a left and right identity.  For instance,
 the natural numbers along with multiplication form a monoid with 1
-serving as the left and right identity.  That is, temporarily using
-`*` to mean arithmetic multiplication, `1 * u == u == u * 1` for all
+serving as the left and right identity.  That is, `1 * u == u == u * 1` for all
 `u`, and `(u * v) * w == u * (v * w)` for all `u`, `v`, and `w`.  As
 presented here, a monad is not exactly a monoid, because (unlike the
 arguments of a monoid operation) the two arguments of the bind are of
 different types.  But it's possible to make the connection between
 monads and monoids much closer. This is discussed in [Monads in Category
-Theory](/advanced_notes/monads_in_category_theory).
+Theory](/advanced_topics/monads_in_category_theory).
 See also <http://www.haskell.org/haskellwiki/Monad_Laws>.
 
 Here are some papers that introduced monads into functional programming:
 
-*      [Eugenio Moggi, Notions of Computation and Monads](http://www.disi.unige.it/person/MoggiE/ftp/ic91.pdf): Information and Computation 93 (1) 1991.
+*      [Eugenio Moggi, Notions of Computation and Monads](http://www.disi.unige.it/person/MoggiE/ftp/ic91.pdf): Information and Computation 93 (1) 1991. Would be very difficult reading for members of this seminar. However, the following two papers should be accessible.
+
+*      [Philip Wadler. The essence of functional programming](http://homepages.inf.ed.ac.uk/wadler/papers/essence/essence.ps):
+invited talk, *19'th Symposium on Principles of Programming Languages*, ACM Press, Albuquerque, January 1992.
+<!--   This paper explores the use monads to structure functional programs. No prior knowledge of monads or category theory is required.
+       Monads increase the ease with which programs may be modified. They can mimic the effect of impure features such as exceptions, state, and continuations; and also provide effects not easily achieved with such features. The types of a program reflect which effects occur.
+       The first section is an extended example of the use of monads. A simple interpreter is modified to support various extra features: error messages, state, output, and non-deterministic choice. The second section describes the relation between monads and continuation-passing style. The third section sketches how monads are used in a compiler for Haskell that is written in Haskell.-->
 
 *      [Philip Wadler. Monads for Functional Programming](http://homepages.inf.ed.ac.uk/wadler/papers/marktoberdorf/baastad.pdf):
 in M. Broy, editor, *Marktoberdorf Summer School on Program Design
 Calculi*, Springer Verlag, NATO ASI Series F: Computer and systems
 sciences, Volume 118, August 1992. Also in J. Jeuring and E. Meijer,
 editors, *Advanced Functional Programming*, Springer Verlag, 
-LNCS 925, 1995. Some errata fixed August 2001.  This paper has a great first
-line: **Shall I be pure, or impure?**
+LNCS 925, 1995. Some errata fixed August 2001.
 <!--   The use of monads to structure functional programs is described. Monads provide a convenient framework for simulating effects found in other languages, such as global state, exception handling, output, or non-determinism. Three case studies are looked at in detail: how monads ease the modification of a simple evaluator; how monads act as the basis of a datatype of arrays subject to in-place update; and how monads can be used to build parsers.-->
 
-*      [Philip Wadler. The essence of functional programming](http://homepages.inf.ed.ac.uk/wadler/papers/essence/essence.ps):
-invited talk, *19'th Symposium on Principles of Programming Languages*, ACM Press, Albuquerque, January 1992.
-<!--   This paper explores the use monads to structure functional programs. No prior knowledge of monads or category theory is required.
-       Monads increase the ease with which programs may be modified. They can mimic the effect of impure features such as exceptions, state, and continuations; and also provide effects not easily achieved with such features. The types of a program reflect which effects occur.
-       The first section is an extended example of the use of monads. A simple interpreter is modified to support various extra features: error messages, state, output, and non-deterministic choice. The second section describes the relation between monads and continuation-passing style. The third section sketches how monads are used in a compiler for Haskell that is written in Haskell.-->
-
-*      [Daniel Friedman. A Schemer's View of Monads](/schemersviewofmonads.ps): from <https://www.cs.indiana.edu/cgi-pub/c311/doku.php?id=home> but the link above is to a local copy.
 
-There's a long list of monad tutorials on the [[Offsite Reading]] page. Skimming the titles makes me laugh.
+There's a long list of monad tutorials on the [[Offsite Reading]] page. (Skimming the titles is somewhat amusing.) If you are confused by monads, make use of these resources. Read around until you find a tutorial pitched at a level that's helpful for you.
 
 In the presentation we gave above---which follows the functional programming conventions---we took `unit`/return and `bind` as the primitive operations. From these a number of other general monad operations can be derived. It's also possible to take some of the others as primitive. The [Monads in Category
-Theory](/advanced_notes/monads_in_category_theory) notes do so, for example.
+Theory](/advanced_topics/monads_in_category_theory) notes do so, for example.
 
 Here are some of the other general monad operations. You don't have to master these; they're collected here for your reference.
 
@@ -342,7 +500,7 @@ that is:
 
 You could also do `bind u (fun x -> v)`; we use the `_` for the function argument to be explicit that that argument is never going to be used.
 
-The `lift` operation we asked you to define for last week's homework is a common operation. The second argument to `bind` converts `'a` values into `'b m` values---that is, into instances of the monadic type. What if we instead had a function that merely converts `'a` values into `'b` values, and we want to use it with our monadic type. Then we "lift" that function into an operation on the monad. For example:
+The `lift` operation we asked you to define for last week's homework is a common operation. The second argument to `bind` converts `'a` values into `'b m` values---that is, into instances of the monadic type. What if we instead had a function that merely converts `'a` values into `'b` values, and we want to use it with our monadic type? Then we "lift" that function into an operation on the monad. For example:
 
        # let even x = (x mod 2 = 0);;
        val g : int -> bool = <fun>
@@ -417,15 +575,15 @@ Monad outlook
 -------------
 
 We're going to be using monads for a number of different things in the
-weeks to come.  The first main application will be the State monad,
+weeks to come.  One major application will be the State monad,
 which will enable us to model mutation: variables whose values appear
 to change as the computation progresses.  Later, we will study the
 Continuation monad.
 
-In the meantime, we'll look at several linguistic applications for monads, based
-on what's called the *reader monad*.
+But first, we'll look at several linguistic applications for monads, based
+on what's called the *Reader monad*.
 
-##[[Reader monad]]##
+##[[Reader monad for Variable Binding]]##
 
-##[[Intensionality monad]]##
+##[[Reader monad for Intensionality]]##