Merge branch 'working'
authorJim <jim.pryor@nyu.edu>
Fri, 20 Mar 2015 22:46:27 +0000 (18:46 -0400)
committerJim <jim.pryor@nyu.edu>
Fri, 20 Mar 2015 22:46:27 +0000 (18:46 -0400)
* working:
  provide simplified untyped_evaluator (complete version)

code/ski_evaluator.ml
content.mdwn
exercises/_assignment6.mdwn [deleted file]
exercises/assignment7.mdwn [new file with mode: 0644]
index.mdwn
topics/_week8_binding.mdwn [new file with mode: 0644]
topics/_week8_intensionality.mdwn [new file with mode: 0644]
topics/_week8_monads_in_general.mdwn [deleted file]
topics/week6_plexy.mdwn
topics/week7_combinatory_evaluator.mdwn
topics/week7_introducing_monads.mdwn

index f0b4d16..742d63d 100644 (file)
@@ -21,12 +21,12 @@ let rec reduce_try2 (t:term):term = match t with
                             in reduce_try2 t''
                        else t'
 
-let rec reduce_lazy (t:term):term = match t with
+let rec reduce_try3 (t:term):term = match t with
   | I -> I
   | K -> K
   | S -> S
   | App (a, b) ->
-      let t' = App (reduce_lazy a, b) in
+      let t' = App (reduce_try3 a, b) in
       if (is_redex t') then let t'' = reduce_if_redex t'
-                            in reduce_lazy t''
+                            in reduce_try3 t''
                        else t'
index 1178c43..f829610 100644 (file)
@@ -121,4 +121,5 @@ Week 7:
 
 *   [[Combinatory evaluator|topics/week7_combinatory_evaluator]]
 *   Interpreter for Lambda terms
-*   [[Introducing Monads|topics/week7_introducing_monads]]
+*   [[Introducing Monads|topics/week7_introducing_monads]] (updated Fri 20 Mar)
+*   [[Homework for week 7|exercises/assignment7]]
diff --git a/exercises/_assignment6.mdwn b/exercises/_assignment6.mdwn
deleted file mode 100644 (file)
index ebc20e0..0000000
+++ /dev/null
@@ -1,180 +0,0 @@
-# Assignment 6 (week 7)
-
-## Evaluation order in Combinatory Logic
-
-1. Give a term that the lazy evaluators (either [[the Haskell
-evaluator|code/ski_evaluator.hs]], or the lazy version of [[the OCaml
-evaluator|code/ski_evaluator.ml]]) do not evaluate all the way to a
-normal form, i.e., that contains a redex somewhere inside of it after
-it has been reduced.
-
-2. One of the [[criteria we established for classifying reduction
-strategies|topics/week3_evaluation_order]] strategies is whether they
-reduce subexpressions hidden under lambdas.  That is, for a term like
-`(\x y. x z) (\x. x)`, do we reduce to `\y.(\x.x) z` and stop, or do
-we reduce further to `\y.z`?  Explain what the corresponding question
-would be for CL. Using the eager version of the OCaml CL evaluator,
-prove that the evaluator does reduce expressions inside of at least
-some "functional" CL expressions.  Then provide a modified evaluator
-that does not perform reductions in those positions. (Just give the
-modified version of your recursive reduction function.)
-
-
-## Evaluation in the untyped lambda calculus: substitution
-
-Having sketched the issues with a discussion of Combinatory Logic,
-we're going to begin to construct an evaluator for a simple language
-that includes lambda abstraction.  In this problem set, we're going to
-work through the issues twice: once with a function that does
-substitution in the obvious way.  You'll see it's somewhat
-complicated.  The complications come from the need to worry about
-variable capture.  (Seeing these complications should give you an
-inkling of why we presented the evaluation order discussion using
-Combinatory Logic, since we don't need to worry about variables in
-CL.)
-
-We're not going to ask you to write the entire program yourself.
-Instead, we're going to give you [[the complete program, minus a few
-little bits of glue|code/reduction_with_substitution.ml]].  What you
-need to do is understand how it all fits together.  When you do,
-you'll understand how to add the last little bits to make functioning
-program.
-
-1. In the previous homework, you built a function that took an
-identifier and a lambda term and returned a boolean representing
-whether that identifier occured free inside of the term.  Your first
-task is to complete the `free_in` function, which has been crippled in
-the code base (look for lines that say `COMPLETE THIS LINE`).  Once
-you have your function working, you should be able to run queries such
-as this:
-
-    # free_in "x" (App (Abstract ("x", Var "x"), Var "x"));;
-    - : bool = true
-
-2. Once you get the `free_in` function working, you'll need to
-complete the `substitute` function.  Sample target:
-
-    # substitute (App (Abstract ("x", ((App (Abstract ("x", Var "x"), Var "y")))), Constant (Num 3))) "y" (Constant (Num 4));;
-    - : lambdaTerm = App (Abstract ("x", App (Abstract ("x", Var "x"), Constant (Num 4))), Constant (Num 3))
-
-By the way, you'll see a new wrinkle on OCaml's pattern-matching
-construction: `| PATTERN when x = 2 -> RESULT`.  This means that a
-match with PATTERN is only triggered if the boolean condition in the
-`when` clause evaluates to true.
-
-3. Once you have completed the previous two problems, you'll have a
-complete evaluation program. Here's a simple sanity check for when you
-get it working:
-
-    # reduce (App (Abstract ("x", Var "x"), Constant (Num 3)));;
-    - : lambdaTerm = Constant (Num 3)
-
-4. What kind of evaluation strategy does this evaluator use?  In
-particular, what are the answers to the three questions about
-evaluation strategy as given in the discussion of [[evaluation
-strategies|topics/week3_evaluation_order]] as Q1, Q2, and Q3?
-
-## Evaluation in the untyped calculus: environments and closures
-
-Ok, the previous strategy sucked: tracking free and bound variables,
-computing fresh variables, it's all super complicated.
-
-Here's a better strategy. Instead of keeping all of the information
-about which variables have been bound or are still free implicitly
-inside of the terms, we'll keep score.  This will require us to carry
-around a scorecard, which we will call an "environment".  This is a
-familiar strategy for philosophers of language and for linguists,
-since it amounts to evaluating expressions relative to an assignment
-function.  The difference between the assignment function approach
-above, and this approach, is one huge step towards monads.
-
-5. First, you need to get [[the evaluation
-code|code/reduction_with_environments.ml]]  working.  Look in the
-code for places where you see "not yet implemented", and get enough of
-those places working that you can use the code to evaluate terms.
-
-6. A snag: what happens when we want to replace a variable with a term
-that itself contains a free variable?  
-
-        term          environment
-        ------------- -------------
-        (\w.(\y.y)w)2 []
-        (\y.y)w       [w->2]
-        y             [w->2, y->w]
-
-In the first step, we bind `w` to the argument `2`.  In the second
-step, we bind `y` to the argument `w`.  In the third step, we would
-like to replace `y` with whatever its current value is according to
-our scorecard.  On the simple-minded view, we would replace it with
-`w`.  But that's not the right result, because `w` itself has been
-mapped onto 2.  What does your evaluator code do?
-
-We'll guide you to a solution involving closures.  The first step is
-to allow values to carry around a specific environment with them:
-
-     type value = LiteralV of literal | Closure of lambdaTerm * env
-
-This will provide the extra information we need to evaluate an
-identifier all the way down to the correct final result.  Here is a
-[[modified version of the evaluator that provides all the scaffoling for
-passing around closures|exercises/reduction_with_closures]].
-The problem is with the following line:
-
-         | Closure (Abstract(bound_ident, body), saved_r) -> eval body (push bound_ident arg saved_r) (* FIX ME *)
-
-What should it be in order to solve the problem?
-
-
-## Monads
-
-Mappables (functors), MapNables (applicatives functors), and Monads
-(composables) are ways of lifting computations from unboxed types into
-boxed types.  Here, a "boxed type" is a type function with one missing
-piece, which we can think of as a function from a type to a type.
-Call this type function M, and let P, Q, R, and S be variables over types.
-
-Recall that a monad requires a singleton function 1:P-> MP, and a
-composition operator >=>: (P->MQ) -> (Q->MR) -> (P->MR) [the type for
-the composition operator given here corrects a "type"-o from the class handout]
-that obey the following laws:
-
-    1 >=> k = k
-    k >=> 1 = k 
-    j >=> (k >=> l) = (j >=> k) >=> l
-
-For instance, the identity monad has the identity function I for 1
-and ordinary function composition (o) for >=>.  It is easy to prove
-that the laws hold for any expressions j, k, and l whose types are
-suitable for 1 and >=>:
-
-    1 >=> k == I o k == \p. I (kp) ~~> \p.kp ~~> k
-    k >=> 1 == k o I == \p. k (Ip) ~~> \p.kp ~~> k
-
-    (j >=> k) >=> l == (\p.j(kp)) o l == \q.(\p.j(kp))(lq) ~~> \q.j(k(lq))
-    j >=> (k >=> l) == j o (k o l) == j o \p.k(lp) == \q.j(\p.k(lp)q) ~~> \q.j(k(lq))
-
-1. On a number of occasions, we've used the Option type to make our
-conceptual world neat and tidy (for instance, think of the discussion
-of Kaplan's Plexy).  As we learned in class, there is a natural monad
-for the Option type.  Borrowing the notation of OCaml, let's say that
-"`'a option`" is the type of a boxed `'a`, whatever type `'a` is.
-More specifically,
-
-     'a option = Nothing | Just 'a
-
-Then the obvious singleton for the Option monad is \p.Just p.  Give
-(or reconstruct) the composition operator >=> we discussed in class.
-Show your composition operator obeys the monad laws.
-
-2. Do the same with lists.  That is, given an arbitrary type
-'a, let the boxed type be ['a], i.e., a list of objects of type 'a.  The singleton
-is `\p.[p]`, and the composition operator is 
-
-       >=> (first:P->[Q]) (second:Q->[R]) :(P->[R]) = List.flatten (List.map f (g a))
-
-For example:
-
-     f p = [p, p+1]
-     s q = [q*q, q+q]
-     >=> f s 7 = [49, 14, 64, 16]
-
diff --git a/exercises/assignment7.mdwn b/exercises/assignment7.mdwn
new file mode 100644 (file)
index 0000000..ea387b9
--- /dev/null
@@ -0,0 +1,127 @@
+# Assignment 7
+
+There is no separate assignment 6. (There was a single big assignment for weeks 5 and 6, and
+we're going to keep the assignment numbers in synch with the weeks.)
+
+## Evaluation order in Combinatory Logic
+
+1. Give a term that the lazy evaluators (either [[the Haskell
+evaluator|code/ski_evaluator.hs]], or the lazy version of [[the OCaml
+evaluator|code/ski_evaluator.ml]]) do not evaluate all the way to a
+normal form, that is, that contains a redex somewhere inside of it after
+it has been reduced.
+
+2. One of the [[criteria we established for classifying reduction
+strategies|topics/week3_evaluation_order]] strategies is whether they
+reduce subterms hidden under lambdas.  That is, for a term like
+`(\x y. x z) (\x. x)`, do we reduce to `\y.(\x.x) z` and stop, or do
+we reduce further to `\y.z`?  Explain what the corresponding question
+would be for CL. Using the eager version of the OCaml CL evaluator (`reduce_try2`),
+prove that the evaluator does reduce terms inside of at least
+some "functional" CL terms.  Then provide a modified evaluator
+that does not perform reductions in those positions. (Just give the
+modified version of your recursive reduction function.)
+
+
+## Evaluation in the untyped lambda calculus: substitute-and-repeat
+
+Having sketched the issues with a discussion of Combinatory Logic,
+we're going to begin to construct an evaluator for a simple language
+that includes lambda abstraction.  In this problem set, we're going to
+work through the issues twice: once with a function that does
+substitution in the obvious way, and keeps reducing-and-repeating until
+there are no more eligible redexes. You'll see it's somewhat
+complicated.  The complications come from the need to worry about
+variable capture. (Seeing these complications should give you an
+inkling of why we presented the evaluation order discussion using
+Combinatory Logic, since we don't need to worry about variables in
+CL.)
+
+We're not going to ask you to write the entire program yourself.
+Instead, we're going to give you almost the complete program, with a few gaps
+in it that you have to complete. You have to understand enough to
+add the last pieces to make the program function.
+
+We're still writing up the (substantial) exposition of this, and will post a link
+to it here soon.
+
+## Evaluation in the untyped lambda calculus: environments
+
+The previous strategy is nice because it corresponds so closely to the
+reduction rules we give when specifying our lambda calculus. (Including
+specifying evaluation order, which redexes it's allowed to reduce, and
+so on.) But keeping track of free and bound variables, computing fresh
+variables when needed, that's all a pain.
+
+Here's a better strategy. Instead of keeping all of the information
+about which variables have been bound or are still free implicitly
+inside of the terms, we'll keep a separate scorecard, which we will call an "environment".  This is a
+familiar strategy for philosophers of language and for linguists,
+since it amounts to evaluating terms relative to an assignment
+function. The difference between the substitute-and-repeat approach
+above, and this approach, is one huge step towards monads.
+
+We're still writing up the exposition of this, too, and will post a link
+to it here soon.
+
+
+## Monads
+
+Mappables (functors), MapNables (applicative functors), and Monads
+(composables) are ways of lifting computations from unboxed types into
+boxed types.  Here, a "boxed type" is a type function with one unsaturated
+hole (which may have several occurrences). We can think of the box type
+as a function from a type to a type. Call this type function M, and let P, Q, R, and S be schematic variables over types.
+
+Recall that a monad requires a singleton function `mid : P-> MP`, and a
+composition operator like `>=> : (P-><u>Q</u>) -> (Q-><u>R</u>) -> (P-><u>R</u>)`.
+
+As we said in the notes, we'll move freely back and forth between using `>=>` and using `<=<` (aka `mcomp`), which
+is just `>=>` with its arguments flipped. `<=<` has the virtue that it corresponds more
+closely to the ordinary mathematical symbol `○`. But `>=>` has the virtue
+that its types flow more naturally from left to right.
+
+Anyway, `mid` and (let's say) `<=<` have to obey the following Monad Laws:
+
+    mid <=< k = k
+    k <=< mid = k 
+    j <=< (k <=< l) = (j <=< k) <=< l
+
+For example, the Identity monad has the identity function `I` for `mid`
+and ordinary function composition `○` for `<=<`.  It is easy to prove
+that the laws hold for any terms `j`, `k`, and `l` whose types are
+suitable for `mid` and `<=<`:
+
+    mid <=< k == I ○ k == \p. I (k p) ~~> \p. k p ~~> k
+    k <=< mid == k ○ I == \p. k (I p) ~~> \p. k p ~~> k
+
+    (j <=< k) <=< l == (\p. j (k p)) ○ l == \q. (\p. j (k p)) (l q) ~~> \q. j (k (l q))
+    j <=< (k <=< l) == j ○ (k ○ l) == j ○ (\p. k (l p)) == \q. j ((\p. k (l p)) q) ~~> \q. j (k (l q))
+
+1.  On a number of occasions, we've used the Option/Maybe type to make our
+conceptual world neat and tidy (for instance, think of [[our discussion
+of Kaplan's Plexy|topics/week6_plexy]]).  As we learned in class, there is a natural monad
+for the Option type. Using the vocabulary of OCaml, let's say that
+"`'a option`" is the type of a boxed `'a`, whatever type `'a` is.
+More specifically,
+
+        type 'a option = None | Some 'a
+
+    (If you have trouble keeping straight what is the OCaml terminology for this and what is the Haskell terminology, don't worry, we do too.)
+
+    Now the obvious singleton for the Option monad is `\p. Some p`.  Give
+(or reconstruct) either of the composition operators `>=>` or `<=<`.
+Show that your composition operator obeys the Monad Laws.
+
+2.  Do the same with lists.  That is, given an arbitrary type
+`'a`, let the boxed type be `['a]` or `'a list`, that is, lists of objects of type `'a`.  The singleton
+is `\p. [p]`, and the composition operator is:
+
+        let (>=>) (j : 'a -> 'b list) (k : 'b -> 'c list) : 'a -> 'c list =
+          fun a -> List.flatten (List.map k (j a))
+
+    For example:
+
+        let j a = [a; a+1];;
+        let k b = [b*b; b+b];;
+        (j >=> k) 7 (* ==> [49; 14; 64; 16] *)
index ea4f3d9..a198e05 100644 (file)
@@ -159,7 +159,7 @@ Practical advice for working with OCaml and/or Haskell (all will be posted soon)
 
 (**Week 7**) Thursday March 12
 
-> Topics: [[Combinatory evaluator|topics/week7_combinatory_evaluator]]; Interpreter for Lambda terms; [[Introducing Monads|topics/week7_introducing_monads]]
+> Topics: [[Combinatory evaluator|topics/week7_combinatory_evaluator]]; Interpreter for Lambda terms; [[Introducing Monads|topics/week7_introducing_monads]] (updated Fri 20 Mar); [[Homework|exercises/assignment7]]
 
 <!--
 (**Week 8**) Thursday March 26
diff --git a/topics/_week8_binding.mdwn b/topics/_week8_binding.mdwn
new file mode 100644 (file)
index 0000000..ce4d087
--- /dev/null
@@ -0,0 +1,302 @@
+[[!toc]]
+
+Substitution versus Environment-based Semantics
+-----------------------------------------------
+
+Let's step back and consider the semantics we've assumed so far for our lambda calculi. We've been doing this:
+
+       (\x. M) N ~~> M {x <- N}
+
+where `M {x <- N}` is the result of substituting N in for free occurrences of `x` in `M`.
+
+What do I mean by calling this a "semantics"? Wasn't this instead part of our proof-theory? Haven't we neglected to discuss any model theory for the lambda calculus?
+
+Well, yes, that's right, we haven't much discussed what computer scientists call *denotational semantics* for the lambda calculus. That's what philosophers and linguists tend to think of as "semantics."
+
+But computer scientists also recognize what they call *operational semantics* and *axiomatic semantics*. The former consists in the specification of an "abstract machine" for evaluating complex expressions of the language. The latter we won't discuss.
+
+When it comes down to it, I'm not sure what difference there is between an operational semantics and a proof theory; though it should be noted that the operational semantics generally *don't* confine themselves to only using abstract machines whose transitions are identical to the ones licensed in the formal system being interpreted. Instead, any viable algorithm for reducing expressions to some sort of normal form (when they can be so reduced) would be entertained.
+
+If we think of the denotations of lambda terms as sets of inter-convertible terms, and let the sets which have normal forms use that normal form as their
+representative, then operational semantics can be thought of as algorithms for
+deriving what a formula's denotation is. But it's not necessary to think of the denonations of lambda terms in that way; and even if we do, matters are complicated by the presence of non-normalizing terms.
+
+In any case, the lambda evaluator we use on our website does evaluate expressions using the kind of operational semantics described above. We can call that a "substitution-based" semantics.
+
+Let's consider a different kind of operational semantics. Instead of substituting `N` in for `x`, why don't we keep some extra data-structure on the side, where we note that `x` should now be understood to evaluate to whatever `N` does? In computer science jargon, such a data-structure is called an **environment**. Philosophers and linguists would tend to call it an **assignment** (though there are some subtleties about whether these are the same thing, which we'll discuss).
+
+[Often in computer science settings, the lambda expression to be evaluated is first translated into **de Bruijn notation**, which we discussed in the first week of term. That is, instead of:
+
+       \x. x (\y. y x)
+
+we have:
+
+       \. 1 (\. 1 2)
+
+where each argument-occurrence records the distance between that occurrence and the `\` which binds it. This has the advantage that the environment can then just be a stack, with the top element of the stack being what goes in for the outermost-bound argument, and so on.
+
+Some students have asked: why do we need de Bruijn notation to represent environments that way? Can't we just assume our variables are of the form <code>x<sub>1</sub>, x<sub>2</sub>, x<sub>3</sub></code>, and so on? And then the values that get assigned to those variables could just be kept in a stack, with the first value understood to be assigned to <code>x<sub>1</sub></code>, and so on. Yes, we could do that. But the advantage of the de Bruijn notation is that we don't have to keep track of which variable is associated with which lambda binder. In the de Bruijn framework, the outermost binder always goes with the top-most member of the stack. In the proposed alternative, that's not so: we could have:
+
+<pre><code>\x<sub>2</sub>. x<sub>2</sub> (\x<sub>8</sub>. x<sub>8</sub> x<sub>2</sub>)
+</code></pre>
+
+In any event, though, we won't make use of de Bruijn notation because, though it makes the semantic algorithms more elegant, it also adds an extra level of conceptual complexity, which we don't want to do.]
+
+Now with the environment-based semantics, instead of evaluating terms using substitution, like this:
+
+       (\x. M) N ~~> M {x <- N}
+
+we'll instead evaluate them by manipulating their environment. To intepret `(\x. M) N` in environment `e`, we'll interpret `M` in an environment like `e {x:= N}` where `x` may have been changed to now be assigned to `N`.
+
+A few comments. First, what the environment associates with the variable `x` will be expressions of the lambda calculus we're evaluating. If we understand the evaluation to be call-by-name, these expressions may be complexes of the form `N P`. If on the other hand, we understand the evaluation to be call-by-value, then these expressions will always be fully evaluated before being inserted into the environment. That means they'll never be of the form `N P`; but only of the form `y` or `\y. P`. The latter kinds of expressions are called "values." But "values" here are just certain kinds of expressions. (They *could* be the denotations of lambda expressions, if one thinks of the lambda expressions as all having normal-form lambda terms as their denotations, when possible.)
+
+Second, there is a subtlety here we haven't yet discussed. Consider what should be the result of this:
+
+       let x = 1
+       in let f = \y. x
+       in let x = 2
+       in f 0
+
+If we interpret the `x` in `\y. x` by the value it had where that function was being declared, and bound to `f`, then this complex expression should return `1`. If on other hand we interpret the `x` to have the value it has where that function is given an argument and reduced, then the complex should return `2`.
+
+There is no right or wrong behavior here. Both are reasonable. The former behavior is called **lexical scoping**, and it's what we get in the untyped lambda calculus, for example. It's also what's most common in functional programming languages. It's easier for programmers to reason about.
+
+The latter behavior is called **dynamic scoping**. Often it's easier for language-designers to implement. It is also useful in certain settings. But we will assume we're dealing with lexical scoping.
+
+To implement lexical scoping, you can't just associate the bare formula `\y. x` to the variable `f` in an environment. You also have to keep track of what is the value in that context of all the free variables in the formula. This combination of a function expression together with the values of its free variables is called a **function closure**. There are different techniques for handling these. The technique we'll use here is conceptually simple: it just stashes away both the formula `\y. x` and a copy of the current environment. So even if we're later asked to evaluate `f` in a different environment, we have the original environment to use to lookup values for`f`'s free variables. This is conceptually simple---but inefficient, because it stashes a copy of the entire current environment, when really we only need that part of the environment relevant to a few free variables. If you care to read up more about
+operational semantics for the lambda calculus, or the underpinnings of how Scheme or OCaml interpreters work under the hood, you can learn about other more elegant techniques. Here we'll keep things conceptually simple.
+
+With these ideas settled, then, we can present an environment-based operational semantics for the untyped lambda calculus. Here is a call-by-value version, which assumes that expressions are always fully evaluated before being inserted into the environment.
+
+1.     When `e` assigns some term `v` to `x`, then `x` fully (that is, terminally) reduces in environment `e` to `v`. We write that as: `(e |- x) ==> v`.
+
+2.     `(e |- \x. M) ==> closure(e, \x. M)`, where a closure is some data-structure (it might just be a pair of the environment `e` and the formula `\x. M`).
+
+3.     If `(e |- M) ==> closure(e2, \x. M2)` and `(e |- N) ==> v` and `(e2 {x:=v} |- M2) ==> u`, then `(e |- M N) ==> u`. Here `e2 {x:=v}` is the environment which is just like `e2` except it assigns `v` to `x`.
+
+
+Explicitly manipulating the environment
+---------------------------------------
+
+In the machinery we just discussed, the environment handling was no part of the language being interpreted. It all took place in the interpreting algorithm. Sometimes, though, it's convenient to explicitly manipulate the environment in your program; or at least, some special portion of the environment, set aside to be manipulated in that way.
+
+For example, a common programming exercise when students are learning languages like OCaml is to implement a simple arithmetic calculator. You'll suppose you're given some expressions of the following type:
+
+       type term = Constant of int
+               | Multiplication of (term * term)
+               | Addition of (term*term)
+               | Variable of char
+               | Let of (char*term*term);;
+
+and then you'd evaluate it something like this:
+
+       let rec eval (t : term) = match t with
+                 Constant x -> x
+               | Multiplication (t1,t2) -> (eval t1) * (eval t2)
+               | Addition (t1,t2) -> (eval t1) + (eval t2)
+               | Variable c -> ... (* we'll come back to this *)
+               | Let (c,t1,t2) -> ... (* this too *)
+
+With that in hand, you could then evaluate complex terms like `Addition(Constant 1, Multiplication(Constant 2, Constant 3))`.
+
+But then how should you evaluate terms like `Let('x',Constant 1,Addition(Variable 'x', Constant 2))`? We'd want to carry along an environment that recorded that `'x'` had been associated with the term `Constant 1`, so that we could retrieve that value when evaluating `Addition(Variable 'x', Constant 2)`.
+
+Notice that here our environments associate variables with (what from the perspective of our calculator language are) *real* values, like `2`, not just value-denoting terms like `Constant 2`.
+
+We'll work with a simple model of environments. They'll just be lists. So the empty environment is `[]`. To modify an environment `e` like this: `e {x:=1}`, we'll use:
+
+       ('x', 1) :: e
+
+that is, `e` is a list of pairs, whose first members are `char`s, and whose second members are evaluation results. To lookup a value `'x'` in `e`, we can use the `List.assoc` function, which behaves like this:
+
+       # List.assoc 'x' [('x',1); ('y',2)];;
+       - : int = 1
+       # List.assoc 'z' [('x',1); ('y',2)];;
+       Exception: Not_found.
+
+Then we should give our `eval` function an extra argument for the environment:
+
+       let rec eval (t : term) (e: (char * int) list) = match t with
+                 Constant x -> x
+               | Multiplication (t1,t2) -> (eval t1 e) * (eval t2 e)
+               | Addition (t1,t2) -> (eval t1 e) + (eval t2 e)
+               | Variable c ->
+                       (* lookup the value of c in the current environment
+                          This will fail if c isn't assigned anything by e *)
+                 List.assoc c e
+               | Let (c,t1,t2) -> 
+                       (* evaluate t2 in a new environment where c has been associated
+                          with the result of evaluating t1 in the current environment *)
+                 eval t2 ((c, eval t1 e) :: e)
+
+Great! Now we've built a simple calculator with let-expressions.
+
+
+Monadizing it
+-------------
+
+As the calculator gets more complex though, it will become more tedious and unsatisfying to have all the clauses like:
+
+               | Addition (t1,t2) -> (eval t1 e) + (eval t2 e)
+
+have to explicitly pass around an environment that they're not themselves making any use of. Would there be any way to hide that bit of plumbing behind the drywall?
+
+Yes! You can do so with a monad, in much the same way we did with our checks for divide-by-zero failures.
+
+Here we'll use a different monad. It's called the **Reader monad**. We define it like this:
+
+       (* we assume we've settled on some implementation of the environment *)
+       type env = (char * int) list;;
+
+       (* here's the type of our Reader monad *)
+       type 'a reader = env -> 'a;;
+
+       (* here's our unit operation; it creates a reader-monad value that
+          ignores the environment and returns x *)
+       let unit x = fun (e : env) -> x;;
+
+       (* here's our bind operation; how does it work? *)
+       let bind (u : 'a reader) (f: 'a -> 'b reader) : 'b reader =
+               (* this can be written more compactly, but having it spelled out
+                  like this will be useful down the road *)
+               fun (e : env) -> let a = u e in let u' = f a in u' e
+
+
+       (* we also define two special-purpose operations on our reader-monad values *)
+       
+       (* evaluate a reader-monad value in a shifted environment; how does this work? *)
+       let shift (c : char) (v : int reader) (u : 'a reader) =
+               fun (e : env) -> u ((c, v e) :: e)
+
+       (* lookup the value of c in the current environment
+          this will fail if c isn't assigned anything by that environment
+          a fuller solution would return an int option instead of
+          returning an int or failing *)
+       let lookup (c : char) : int reader =
+               fun (e : env) -> List.assoc c e 
+       
+
+With this in hand, we can then do our calculator like this. Instead of `int`s, evaluating a term now returns an `int reader`, a monadic value of our new reader-monad type:
+
+       let rec eval (t : term) = match t with
+                 Constant x -> unit x
+               | Multiplication (t1,t2) -> lift2 ( * ) (eval t1) (eval t2)
+               | Addition (t1,t2) -> lift2 ( + ) (eval t1) (eval t2)
+               | Variable c -> lookup c
+               | Let (c,t1,t2) -> shift c (eval t1) (eval t2);;
+
+Now if we try:
+
+       # let result = eval (Let('x',Constant 1,Addition(Variable 'x',Constant 2)));;
+       - : int reader = <fun>
+
+How do we see what integer that evaluates to? Well, it's an int-Reader monad, which is a function from an `env` to an `int`, so we need to give it some `env` to operate on. We can give it the empty environment:
+
+       # result [];;
+       - : int = 3
+
+Great! Now our calculator uses a monad, so it's much higher-tech.
+
+
+Ummm...and why is this useful?
+------------------------------
+
+I guess you haven't you been paying close enough attention, or you don't have much practical experience in linguistics yet.
+
+In Heim and Kratzer's textbook <cite>Semantics in Generative Grammar</cite>, the interpretation of complex phrases like \[[interprets complex phrases]] are trees that look like this:
+
+<blockquote><pre>
+                               VP
+                         /    \
+                        /      \
+                       /        \
+                  /          \
+                 /            \
+                /              NP
+               /              /  \
+          /              /    \
+          V             /      \
+          |            /        \
+\[[interprets]]    AP         N
+                                 / \         |
+                         \[[complex]] \[[phrases]]
+</pre></blockquote>
+
+
+Now the normal way in which the nodes of such trees are related to each other is that the semantic value of a parent node is the result of applying the functional value of one of the daughter nodes to the value of the other daughter node. (The types determine which side is the function and which side is the argument.) One exception to this general rule concerns intersective adjectives. (How does \[[complex]] combine with \[[phrases]]?) We'll ignore that though.
+
+Another exception is that Heim and Kratzer have to postulate a special rule to handle lambda abstraction. (This is their "Predicate Abstraction Rule.") Not only is it a special rule, but it's arguably not even a compositional rule. The basic idea is this. The semantic value of:
+
+       \[[man who(i): Alice spurned i]]
+
+is the result of combining \[[man]], an `e->t` type predicate value, with the adjective-type value of \[[who(i): Alice spurned i]]. As I said, we'll ignore complexities about their treatment of adjectives. But how is \[[who(i): Alice spurned i]] derived? Heim and Kratzer say this is defined only relative to an
+assignment g, and it's defined to be a function from objects x in the domain to the value that \[[Alice spurned i]] has relative to shifted assignment g {i:=x}, which is like g except for assigning object x to variable i. So this is not the result of taking some value \[[who(i)]], and some separate value \[[Alice spurned i]], and supplying one of them to the other as argument to function.
+
+Getting any ideas?
+
+Yes! We can in fact implement this as a Reader monad. And in doing so, we *will* get a value \[[who(i)]] which is a function, and another value \[[Alice spurned i]], to be its argument. So the semantics in the first place again becomes compositional, and in the second place doesn't need any special rule for how \[[who(i): Alice spurned i]] is derived. It uses the same composition rule as other complex expressions.
+
+How does this work?
+
+We set \[[i]] = the reader-monad value `lookup i`.
+
+We set \[[Alice]] = the reader-monad value `unit Alice`.
+
+We have to lift the semantic values of predicates into the Reader monad. So if before we were taking the semantic value of "spurned" to be a function `S` of type `e -> e -> t`, now we set \[[spurned]] = `lift2 S`.
+
+Finally, we set \[[who(i)]] to be:
+
+       fun (u : bool reader) (v : entity reader) ->
+               fun (g : env) -> u (g {i:=v g})
+
+That is, it takes as arguments a clause-type reader-monad `u`, and an entity-type reader-monad `v`, and returns a reader-monad that evaluates `u` in an environment that's modified to assign `v`'s value in that environment to the variable `i`. In other words, this is:
+
+       fun (u : bool reader) (v : entity reader) -> shift i v u
+
+You can trace through what happens then if we apply \[[who(i)]] to \[[Alice spurned i]]:
+
+       \[[Alice spurned i]] = \[[spurned]] \[[i]] \[[Alice]]
+               = (lift2 S) (lookup i) (unit Alice)
+               = bind (lookup i) (fun x -> bind (unit Alice) (fun y -> unit (S x y)))
+
+because of the left-identity rule for `unit`, this is the same as:
+
+               = bind (lookup i) (fun x -> unit (S x Alice))
+
+Substituting in the definition of `bind` for the reader-monad, this is:
+
+               = fun e -> (fun x -> unit (S x Alice)) (lookup i e) e
+               = fun e -> unit (S (lookup i e) Alice) e
+
+Substituting in the definition of `unit`, this is:
+
+               = fun e -> S (lookup i e) Alice
+
+And now supplying \[[Alice spurned i]] as an argument to \[[who(i)]], we get:
+
+       \[[who(i): Alice spurned i]] = \[[who(i)]] \[[Alice spurned i]]
+               = (fun u v -> shift i v u) (fun e -> S (lookup i e) Alice)
+               = fun v -> shift i v (fun e -> S (lookup i e) Alice)
+
+Substituting in the definition of `shift`, this is:
+
+               = fun v -> (fun c v u e -> u ((c, v e) :: e)) i v (fun e -> S (lookup i e) Alice)
+               = fun v -> (fun u e -> u ((i, v e) :: e)) (fun e -> S (lookup i e) Alice)
+               = fun v -> (fun e -> (fun e -> S (lookup i e) Alice) ((i, v e) :: e))
+               = fun v -> (fun e -> S (lookup i ((i, v e) :: e)) Alice)
+               = fun v -> (fun e -> S (v e) Alice)
+
+In other words, it's a function from entity-Reader monads to a function from assignment functions to the result of applying S to the value of that entity reader-monad under that assignment function, and to Alice. Essentially the same as Heim and Kratzer's final value, except here we work with monadic values, such as functions from assignments to entities, rather than bare entities. And our derivation is completely compositional and uses the same composition rules for joining \[[who(i)]] to \[[Alice spurned i]] as it uses for joining \[[spurned]] to \[[i]] and \[[Alice]].
+
+What's not to like?
+
+Well, some of our semantic values here are assignment-shifters:
+
+       \[[who(i)]] = fun u v -> shift i v u
+
+and some philosophers count assignment-shifters as "monsters" and think there can't be any such thing. Well, everyone has their own issues they need to work through.
+
+Later, techniques parallel to what we do here can be used to implement semantics for mutation and dynamic predicate logic. And then again, parallel techniques can be used to implement the "coordinated" semantics that Kit Fine and Jim Pryor favor. We just need different monads in each case.
+
+Want more right now? Then let's look at doing the same thing for [Intensionality](/intensionality_monad).
+
diff --git a/topics/_week8_intensionality.mdwn b/topics/_week8_intensionality.mdwn
new file mode 100644 (file)
index 0000000..4159f84
--- /dev/null
@@ -0,0 +1,226 @@
+Now we'll look at using monads to do intensional function application.
+This is just another application of the Reader monad, not a new monad.
+In Shan (2001) [Monads for natural
+language semantics](http://arxiv.org/abs/cs/0205026v1), Ken shows that
+making expressions sensitive to the world of evaluation is conceptually
+the same thing as making use of the Reader monad.
+This technique was beautifully re-invented
+by Ben-Avi and Winter (2007) in their paper [A modular
+approach to
+intensionality](http://parles.upf.es/glif/pub/sub11/individual/bena_wint.pdf),
+though without explicitly using monads.
+
+All of the code in the discussion below can be found here: [[intensionality-monad.ml]].
+To run it, download the file, start OCaml, and say 
+
+       # #use "intensionality-monad.ml";;
+
+Note the extra `#` attached to the directive `use`.
+
+First, the familiar linguistic problem:
+
+       Bill left.  
+          Cam left.
+          Ann believes [Bill left].
+          Ann believes [Cam left].
+
+We want an analysis on which the first three sentences can be true at
+the same time that the last sentence is false.  If sentences denoted
+simple truth values or booleans, we have a problem: if the sentences
+*Bill left* and *Cam left* are both true, they denote the same object,
+and Ann's beliefs can't distinguish between them.
+
+The traditional solution to the problem sketched above is to allow
+sentences to denote a function from worlds to truth values, what
+Montague called an intension.  So if `s` is the type of possible
+worlds, we have the following situation:
+
+
+<pre>
+Extensional types              Intensional types       Examples
+-------------------------------------------------------------------
+
+S         t                    s->t                    John left
+DP        e                    s->e                    John
+VP        e->t                 (s->e)->s->t            left
+Vt        e->e->t              (s->e)->(s->e)->s->t    saw
+Vs        t->e->t              (s->t)->(s->e)->s->t    thought
+</pre>
+
+This system is modeled on the way Montague arranged his grammar.
+There are significant simplifications: for instance, determiner
+phrases are thought of as corresponding to individuals rather than to
+generalized quantifiers.  
+
+The main difference between the intensional types and the extensional
+types is that in the intensional types, the arguments are functions
+from worlds to extensions: intransitive verb phrases like "left" now
+take so-called "individual concepts" as arguments (type s->e) rather than plain
+individuals (type e), and attitude verbs like "think" now take
+propositions (type s->t) rather than truth values (type t).
+In addition, the result of each predicate is an intension.
+This expresses the fact that the set of people who left in one world
+may be different than the set of people who left in a different world.
+(Normally, the dependence of the extension of a predicate to the world
+of evaluation is hidden inside of an evaluation coordinate, or built
+into the the lexical meaning function, but we've made it explicit here
+in the way that the intensionality monad makes most natural.)
+
+The intensional types are more complicated than the extensional
+types.  Wouldn't it be nice to make the complicated types available
+for those expressions like attitude verbs that need to worry about
+intensions, and keep the rest of the grammar as extensional as
+possible?  This desire is parallel to our earlier desire to limit the
+concern about division by zero to the division function, and let the
+other functions, like addition or multiplication, ignore
+division-by-zero problems as much as possible.
+
+So here's what we do:
+
+In OCaml, we'll use integers to model possible worlds. Characters (characters in the computational sense, i.e., letters like `'a'` and `'b'`, not Kaplanian characters) will model individuals, and OCaml booleans will serve for truth values:
+
+       type s = int;;
+       type e = char;;
+       type t = bool;;
+
+       let ann = 'a';;
+       let bill = 'b';;
+       let cam = 'c';;
+
+       let left1 (x:e) = true;; 
+       let saw1 (x:e) (y:e) = y < x;; 
+
+       left1 ann;; (* true *)
+       saw1 bill ann;; (* true *)
+       saw1 ann bill;; (* false *)
+
+So here's our extensional system: everyone left, including Ann;
+and Ann saw Bill (`saw1 bill ann`), but Bill didn't see Ann.  (Note that the word
+order we're using is VOS, verb-object-subject.)
+
+Now we add intensions.  Because different people leave in different
+worlds, the meaning of *leave* must depend on the world in which it is
+being evaluated:
+
+    let left (x:e) (w:s) = match (x, w) with ('c', 2) -> false | _ -> true;;
+    left ann 1;; (* true: Ann left in world 1 *)
+    left cam 2;; (* false: Cam didn't leave in world 2 *) 
+
+This new definition says that everyone always left, except that 
+in world 2, Cam didn't leave.
+
+Note that although this general *left* is sensitive to world of
+evaluation, it does not have the fully intensionalized type given in
+the chart above, which was `(s->e)->s->t`.  This is because
+*left* does not exploit the additional resolving power provided by
+making the subject an individual concept.  In semantics jargon, we say
+that *leave* is extensional with respect to its first argument.  
+
+Therefore we will adopt the general strategy of defining predicates
+in a way that they take arguments of the lowest type that will allow
+us to make all the distinctions the predicate requires.  When it comes
+time to combine this predicate with monadic arguments, we'll have to
+make use of various lifting predicates.
+
+Likewise, although *see* depends on the world of evaluation, it is
+extensional in both of its syntactic arguments:
+
+    let saw x y w = (w < 2) && (y < x);;
+    saw bill ann 1;; (* true: Ann saw Bill in world 1 *)
+    saw bill ann 2;; (* false: no one saw anyone in world 2 *)
+
+This (again, partially) intensionalized version of *see* coincides
+with the `saw1` function we defined above for world 1; in world 2, no
+one saw anyone.
+
+Just to keep things straight, let's review the facts:
+
+<pre>
+     World 1: Everyone left.
+              Ann saw Bill, Ann saw Cam, Bill saw Cam, no one else saw anyone.              
+     World 2: Ann left, Bill left, Cam didn't leave.
+              No one saw anyone.
+</pre>
+
+Now we are ready for the intensionality monad:
+
+<pre>
+type 'a intension = s -> 'a;;
+let unit x = fun (w:s) -> x;;
+(* as before, bind can be written more compactly, but having
+   it spelled out like this will be useful down the road *)
+let bind u f = fun (w:s) -> let a = u w in let u' = f a in u' w;;
+</pre>
+
+Then the individual concept `unit ann` is a rigid designator: a
+constant function from worlds to individuals that returns `'a'` no
+matter which world is used as an argument.  This is a typical kind of
+thing for a monad unit to do.
+
+Then combining a predicate like *left* which is extensional in its
+subject argument with an intensional subject like `unit ann` is simply bind
+in action:
+
+    bind (unit ann) left 1;; (* true: Ann left in world 1 *)
+    bind (unit cam) left 2;; (* false: Cam didn't leave in world 2 *)
+
+As usual, bind takes a monad box containing Ann, extracts Ann, and
+feeds her to the extensional *left*.  In linguistic terms, we take the
+individual concept `unit ann`, apply it to the world of evaluation in
+order to get hold of an individual (`'a'`), then feed that individual
+to the extensional predicate *left*.
+
+We can arrange for a transitive verb that is extensional in both of
+its arguments to take intensional arguments:
+
+    let lift2' f u v = bind u (fun x -> bind v (fun y -> f x y));;
+
+This is almost the same `lift2` predicate we defined in order to allow
+addition in our division monad example.  The difference is that this
+variant operates on verb meanings that take extensional arguments but
+returns an intensional result.  Thus the original `lift2` predicate
+has `unit (f x y)` where we have just `f x y` here.
+  
+The use of `bind` here to combine *left* with an individual concept,
+and the use of `lift2'` to combine *see* with two intensional
+arguments closely parallels the two of Montague's meaning postulates
+(in PTQ) that express the relationship between extensional verbs and
+their uses in intensional contexts.
+
+<pre>
+lift2' saw (unit bill) (unit ann) 1;;  (* true *)
+lift2' saw (unit bill) (unit ann) 2;;  (* false *)
+</pre>
+
+Ann did see bill in world 1, but Ann didn't see Bill in world 2.
+
+Finally, we can define our intensional verb *thinks*.  *Think* is
+intensional with respect to its sentential complement, though still extensional
+with respect to its subject.  (As Montague noticed, almost all verbs
+in English are extensional with respect to their subject; a possible
+exception is "appear".)
+
+    let thinks (p:s->t) (x:e) (w:s) = 
+      match (x, p 2) with ('a', false) -> false | _ -> p w;;
+
+Ann disbelieves any proposition that is false in world 2.  Apparently,
+she firmly believes we're in world 2.  Everyone else believes a
+proposition iff that proposition is true in the world of evaluation.
+
+    bind (unit ann) (thinks (bind (unit bill) left)) 1;;
+
+So in world 1, Ann thinks that Bill left (because in world 2, Bill did leave).
+
+    bind (unit ann) (thinks (bind (unit cam) left)) 1;;
+
+But in world 1, Ann doesn't believe that Cam left (even though he
+did leave in world 1: `bind (unit cam) left 1 == true`).  Ann's thoughts are hung up on
+what is happening in world 2, where Cam doesn't leave.
+
+*Small project*: add intersective ("red") and non-intersective
+ adjectives ("good") to the fragment.  The intersective adjectives
+ will be extensional with respect to the nominal they combine with
+ (using bind), and the non-intersective adjectives will take
+ intensional arguments.
+
+
diff --git a/topics/_week8_monads_in_general.mdwn b/topics/_week8_monads_in_general.mdwn
deleted file mode 100644 (file)
index 6dfbdeb..0000000
+++ /dev/null
@@ -1,434 +0,0 @@
-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:
-
-*      A complex type that's built around some more basic type. Usually
-       the complex type will be polymorphic, and so can apply to different basic types.
-       In our division example, the polymorphism of the `'a option` type
-       provides a way of building an option out of any other type of object.
-       People often use a container metaphor: if `u` has type `int option`,
-       then `u` is a box that (may) contain an integer.
-
-               type 'a option = None | Some of 'a;;
-
-*      A way to turn an ordinary value into a monadic value.  In OCaml, we
-       did this for any integer `x` by mapping it to
-       the option `Some x`.  In the general case, this operation is
-       known as `unit` or `return.` Both of those names are terrible. This
-       operation is only very loosely connected to the `unit` type we were
-       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.  [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
-       of the singleton function as an example: it takes an ordinary object
-       and returns a set containing that object. In the example we've been
-       considering:
-
-               let unit x = Some x;;
-               val unit : 'a -> 'a option = <fun>
-
-       So `unit` is a way to put something inside of a monadic box. It's crucial
-       to the usefulness of monads that there will be monadic boxes that
-       aren't the result of that operation. In the Option/Maybe monad, for
-       instance, there's also the empty box `None`. In another (whimsical)
-       example, you might have, in addition to boxes merely containing integers,
-       special boxes that contain integers and also sing a song when they're opened. 
-
-       The unit/return operation will always be the simplest, conceptually
-       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`. 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:
-
-               let bind u f = match u with None -> None | Some x -> f x;;
-               val bind : 'a option -> ('a -> 'b option) -> 'b option = <fun>
-
-       Note the type: `bind` takes two arguments: first, a monadic box
-       (in this case, an `'a option`); and second, a function from
-       ordinary objects to monadic boxes. `bind` then returns a monadic
-       value: in this case, a `'b option` (you can start with, e.g., `int option`s
-       and end with `bool option`s).
-
-       Intuitively, the interpretation of what `bind` does is this:
-       the first argument is a monadic value `u`, which 
-       evaluates to a box that (maybe) contains some ordinary value, call it `x`.
-       Then the second argument uses `x` to compute a new monadic
-       value.  Conceptually, then, we have
-
-               let bind u f = (let x = unbox u in f x);;
-
-       The guts of the definition of the `bind` operation amount to
-       specifying how to unbox the monadic value `u`.  In the `bind`
-       operator for the Option monad, we unboxed the monadic value by
-       matching it with the pattern `Some x`---whenever `u`
-       happened to be a box containing an integer `x`, this allowed us to
-       get our hands on that `x` and feed it to `f`.
-
-       If the monadic box didn't contain any ordinary value,
-       we instead pass through the empty box unaltered.
-
-       In a more complicated case, like our whimsical "singing box" example
-       from before, if the monadic value happened to be a singing box
-       containing an integer `x`, then the `bind` operation would probably
-       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
-       useful way.
-
-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`: wherever you see `u >>= f`, that means `bind u f`.
-Wadler uses &#8902;, but that hasn't been widely adopted (unfortunately).
-
-Also, if you ever see this notation:
-
-       do
-               x <- u
-               f x
-
-That's a Haskell shorthand for `u >>= (\x -> f x)`, that is, `bind u f`.
-Similarly:
-
-       do
-               x <- u
-               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.  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. (See our page on [[Translating between OCaml Scheme and Haskell]].) It won't work in
-OCaml. In fact, the `<-` symbol already means something different in OCaml,
-having to do with mutable record fields. We'll be discussing mutation someday
-soon.)
-
-As we proceed, we'll be seeing a variety of other monad systems. For example, another monad is the List monad. Here the monadic type is:
-
-       # type 'a list
-
-The `unit`/return operation is:
-
-       # let unit x = [x];;
-       val unit : 'a -> 'a list = <fun>
-
-That is, the simplest way to lift an `'a` into an `'a list` is just to make a
-singleton list of that `'a`. Finally, the `bind` operation is:
-
-       # let bind u f = List.concat (List.map f u);;
-       val bind : 'a list -> ('a -> 'b list) -> 'b list = <fun>
-       
-What's going on here? Well, consider `List.map f u` first. This goes through all
-the members of the list `u`. There may be just a single member, if `u = unit x`
-for some `x`. Or on the other hand, there may be no members, or many members. In
-any case, we go through them in turn and feed them to `f`. Anything that gets fed
-to `f` will be an `'a`. `f` takes those values, and for each one, returns a `'b list`.
-For example, it might return a list of all that value's divisors. Then we'll
-have a bunch of `'b list`s. The surrounding `List.concat ( )` converts that bunch
-of `'b list`s into a single `'b list`:
-
-       # List.concat [[1]; [1;2]; [1;3]; [1;2;4]]
-       - : int list = [1; 1; 2; 1; 3; 1; 2; 4]
-
-So now we've seen two monads: the Option/Maybe monad, and the List monad. For any
-monadic system, there has to be a specification of the complex monad type,
-which will be parameterized on some simpler type `'a`, and the `unit`/return
-operation, and the `bind` operation. These will be different for different
-monadic systems.
-
-Many monadic systems will also define special-purpose operations that only make
-sense for that system.
-
-Although the `unit` and `bind` operation are defined differently for different
-monadic systems, there are some general rules they always have to follow.
-
-
-The Monad Laws
---------------
-
-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 -> '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>
-
-       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 equivalently `( >>= ) u f` instead of `>>= u
-       f`.
-
-               # unit 2;;
-               - : int option = Some 2
-               # 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;;
-               - : int option = Some 3
-
-               # divide 6 0;;
-               - : int option = None
-               # 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)
-
-       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`.
-
-       Wadler and others try to make this look nicer by phrasing it like this,
-       where U, V, and W are schematic for any expressions with the relevant monadic type:
-
-               (U >>= fun x -> V) >>= fun y -> W  ==  U >>= fun x -> (V >>= fun y -> W)
-
-       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;; 
-               - : int option = Some 3
-               # Some 3 >>= (fun x -> unit x >>= unit);;
-               - : int option = Some 3
-
-               # Some 3 >>= divide 6 >>= divide 2;;
-               - : int option = Some 1
-               # Some 3 >>= (fun x -> divide 6 x >>= divide 2);;
-               - : int option = Some 1
-
-               # Some 3 >>= divide 2 >>= divide 6;;
-               - : int option = None
-               # Some 3 >>= (fun x -> divide 2 x >>= divide 6);;
-               - : int option = None
-
-       Of course, associativity must hold for *arbitrary* functions of
-       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
-       `u` matches `Some x`, and `f x` evalutes to `None`, then both
-       computations will again result in `None`; and if the value of
-       `f x` matches `Some y`, then both computations will evaluate
-       to `g y`.
-
-*      **Right identity: unit is a right identity for bind.**  That is, 
-       `u >>= unit == u` for all monad objects `u`.  For instance,
-
-               # Some 3 >>= unit;;
-               - : int option = Some 3
-               # None >>= unit;;
-               - : 'a option = None
-
-
-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, `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_topics/monads_in_category_theory).
-
-See also:
-
-*      [Haskell wikibook on Monad Laws](http://www.haskell.org/haskellwiki/Monad_Laws).
-*      [Yet Another Haskell Tutorial on Monad Laws](http://en.wikibooks.org/wiki/Haskell/YAHT/Monads#Definition)
-*      [Haskell wikibook on Understanding Monads](http://en.wikibooks.org/wiki/Haskell/Understanding_monads)
-*      [Haskell wikibook on Advanced Monads](http://en.wikibooks.org/wiki/Haskell/Advanced_monads)
-*      [Haskell wikibook on do-notation](http://en.wikibooks.org/wiki/Haskell/do_Notation)
-*      [Yet Another Haskell Tutorial on do-notation](http://en.wikibooks.org/wiki/Haskell/YAHT/Monads#Do_Notation)
-
-
-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. 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.
-<!--   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.-->
-
-
-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_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.
-
-You may sometimes see:
-
-       u >> v
-
-That just means:
-
-       u >>= fun _ -> v
-
-that is:
-
-       bind u (fun _ -> v)
-
-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:
-
-       # let even x = (x mod 2 = 0);;
-       val g : int -> bool = <fun>
-
-`even` has the type `int -> bool`. Now what if we want to convert it into an operation on the Option/Maybe monad?
-
-       # let lift g = fun u -> bind u (fun x -> Some (g x));;
-       val lift : ('a -> 'b) -> 'a option -> 'b option = <fun>
-
-`lift even` will now be a function from `int option`s to `bool option`s. We can
-also define a lift operation for binary functions:
-
-       # let lift2 g = fun u v -> bind u (fun x -> bind v (fun y -> Some (g x y)));;
-       val lift2 : ('a -> 'b -> 'c) -> 'a option -> 'b option -> 'c option = <fun>
-
-`lift2 (+)` will now be a function from `int option`s  and `int option`s to `int option`s. This should look familiar to those who did the homework.
-
-The `lift` operation (just `lift`, not `lift2`) is sometimes also called the `map` operation. (In Haskell, they say `fmap` or `<$>`.) And indeed when we're working with the List monad, `lift f` is exactly `List.map f`!
-
-Wherever we have a well-defined monad, we can define a lift/map operation for that monad. The examples above used `Some (g x)` and so on; in the general case we'd use `unit (g x)`, using the specific `unit` operation for the monad we're working with.
-
-In general, any lift/map operation can be relied on to satisfy these laws:
-
-       * lift id = id
-       * lift (compose f g) = compose (lift f) (lift g)
-
-where `id` is `fun x -> x` and `compose f g` is `fun x -> f (g x)`. If you think about the special case of the map operation on lists, this should make sense. `List.map id lst` should give you back `lst` again. And you'd expect these
-two computations to give the same result:
-
-       List.map (fun x -> f (g x)) lst
-       List.map f (List.map g lst)
-
-Another general monad operation is called `ap` in Haskell---short for "apply." (They also use `<*>`, but who can remember that?) This works like this:
-
-       ap [f] [x; y] = [f x; f y]
-       ap (Some f) (Some x) = Some (f x)
-
-and so on. Here are the laws that any `ap` operation can be relied on to satisfy:
-
-       ap (unit id) u = u
-       ap (ap (ap (unit compose) u) v) w = ap u (ap v w)
-       ap (unit f) (unit x) = unit (f x)
-       ap u (unit x) = ap (unit (fun f -> f x)) u
-
-Another general monad operation is called `join`. This is the operation that takes you from an iterated monad to a single monad. Remember when we were explaining the `bind` operation for the List monad, there was a step where
-we went from:
-
-       [[1]; [1;2]; [1;3]; [1;2;4]]
-
-to:
-
-       [1; 1; 2; 1; 3; 1; 2; 4]
-
-That is the `join` operation.
-
-All of these operations can be defined in terms of `bind` and `unit`; or alternatively, some of them can be taken as primitive and `bind` can be defined in terms of them. Here are various interdefinitions:
-
-       lift f u = u >>= compose unit f
-       lift f u = ap (unit f) u
-       lift2 f u v = u >>= (fun x -> v >>= (fun y -> unit (f x y)))
-       lift2 f u v = ap (lift f u) v = ap (ap (unit f) u) v
-       ap u v = u >>= (fun f -> lift f v)
-       ap u v = lift2 id u v
-       join m2 = m2 >>= id
-       u >>= f = join (lift f u)
-       u >> v = u >>= (fun _ -> v)
-       u >> v = lift2 (fun _ -> id) u v
-
-
-
-Monad outlook
--------------
-
-We're going to be using monads for a number of different things in the
-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.
-
-But first, we'll look at several linguistic applications for monads, based
-on what's called the *Reader monad*.
-
-##[[Reader Monad for Variable Binding]]##
-
-##[[Reader Monad for Intensionality]]##
-
index 864d84e..f258be1 100644 (file)
@@ -7,7 +7,7 @@ meanings with direct reference, and then offers a solution based on
 types.
 
 To grasp the problem, consider a structured-meaning theory of meaning,
-on which the meaning of natural language expressions are represented
+on which the meanings of natural language expressions are represented
 by objects that can have internal structure.
 
     1. The center of mass of the solar system is a point.
@@ -65,7 +65,9 @@ In terms of the type systems we'll be developing over the next few
 weeks, the type of a DP will be a *sum type*: the disjoint union of the
 class of objects that a directly referential term can refer to, and
 the class of objects that can serve as complex meaning structures
-corresponding to DPs as in (1) that are not directly referential.
+corresponding to DPs as in (1) that are not directly referential. 
+Our more systematic type-theoretic treatment permits us to dispense with worries
+about whether the meaning of the DP in (1) might itself be the empty set.
 
 ## Motivating Maybe
 
@@ -86,14 +88,14 @@ sentence *Santa is hungry* means the same thing as *Cupid is
 hungry*.
 
 Setting aside such objections, we will see over and over again the
-utility of the general strategy instantiated in Kaplan's strategy for representing the meaning of
+utility of the general strategy instantiated in Kaplan's proposal for representing the meaning of
 directly-referential expressions:
 
 > Kaplan's rule for directly-referential expressions: a directly referential expression E contributes either:  
-> {}   if there is no object that E refers to, or else  
-> {P}  if E refers to P
+> {}   (or what we'll call `None` or `Nothing`) if there is no object that E refers to, or else  
+> {P}  (or what we'll call `Some P` or `Just P`) if E refers to P
 
-In later weeks, we will call the general form of this technique the "option" or "Maybe" type, and the general strategy for deploying this type "the Maybe monad." (In OCaml one has types like `int option`; in Haskell they are `Maybe Int`.)
+We will call the type used here an "option" or "Maybe" type (from OCaml and Haskell, respectively). And we'll call the general strategy for deploying this type "the Option/Maybe monad."
 
 
 Kaplan, D. 1989. "Demonstratives. In J. Almog, J. Perry, & H. Wettstein
index 9c3ac87..34c4e1c 100644 (file)
@@ -365,14 +365,14 @@ wait until we have Continuation Passing Style transforms.
 The answer to the first question (Can we adjust the OCaml evaluator to
 exhibit lazy behavior?) is quite simple:
 
-    let rec reduce_lazy (t : term) : term = match t with
+    let rec reduce_try3 (t : term) : term = match t with
       | I -> I
       | K -> K
       | S -> S
       | App (a, b) -> 
-          let t' = App (reduce_lazy a, b) in
+          let t' = App (reduce_try3 a, b) in
           if (is_redex t') then let t'' = reduce_if_redex t'
-                                in reduce_lazy t''
+                                in reduce_try3 t''
                            else t'
 
 There is only one small difference from `reduce_try2`: instead of setting `t'` to `App
@@ -381,9 +381,9 @@ There is only one small difference from `reduce_try2`: instead of setting `t'` t
 subexpression at all.  Ever!  The only way to get evaluated is to
 somehow get into functor position.
 
-    # reduce3 (App(App(K,I),skomega));;
+    # reduce_try3 (App(App(K,I),skomega));;
     - : term = I
-    # reduce3 skomega;;
+    # reduce_try3 skomega;;
     C-c C-cInterrupted.
 
 The evaluator now has no trouble finding the normal form for `KIΩ`,
index bb0df8f..4488a59 100644 (file)
@@ -1,4 +1,4 @@
-<!-- λ Λ ∀ ≡ α β γ ρ ω Ω -->
+<!-- λ Λ ∀ ≡ α β γ ρ ω Ω ○ μ η δ ζ ξ ⋆ ★ • ∙ ● 𝟎 𝟏 𝟐 𝟘 𝟙 𝟚 𝟬 𝟭 𝟮 -->
 <!-- Loved this one: http://www.stephendiehl.com/posts/monads.html -->
 
 Introducing Monads
@@ -12,16 +12,24 @@ can be unhelpful. There's a backlash about the metaphors that tells people
 to instead just look at the formal definition. We'll give that to you below, but it's
 sometimes sloganized as
 [A monad is just a monoid in the category of endofunctors, what's the problem?](http://stackoverflow.com/questions/3870088).
-Without some intuitive guidance, this can also be unhelpful. We'll try to find a good balance. 
+Without some intuitive guidance, this can also be unhelpful. We'll try to find a good balance.
+
 
 The closest we will come to metaphorical talk is to suggest that
-monadic types place objects inside of *boxes*, and that monads wrap
-and unwrap boxes to expose or enclose the objects inside of them. In
+monadic types place values inside of *boxes*, and that monads wrap
+and unwrap boxes to expose or enclose the values inside of them. In
 any case, our emphasis will be on starting with the abstract structure
 of monads, followed by instances of monads from the philosophical and
 linguistics literature.
 
-## Box types: type expressions with one free type variable
+> <small>After you've read this once and are coming back to re-read it to try to digest the details further, the "endofunctors" that slogan is talking about are a combination of our boxes and their associated maps. Their "monoidal" character is captured in the Monad Laws, where a "monoid"---don't confuse with a mon*ad*---is a simpler algebraic notion, meaning a universe with some associative operation that has an identity. For advanced study, here are some further links on the relation between monads as we're working with them and monads as they appear in Category Theory:
+[1](http://en.wikipedia.org/wiki/Outline_of_category_theory)
+[2](http://lambda1.jimpryor.net/advanced_topics/monads_in_category_theory/)
+[3](http://en.wikibooks.org/wiki/Haskell/Category_theory)
+[4](https://wiki.haskell.org/Category_theory), where you should follow the further links discussing Functors, Natural Transformations, and Monads.</small>
+
+
+## Box types: type expressions with one free type variable ##
 
 Recall that we've been using lower-case Greek letters
 <code>&alpha;, &beta;, &gamma;, ...</code> as type variables. We'll
@@ -33,7 +41,7 @@ type variables. For instance, we might have
     P_3 ≡ ∀α. α -> α
     P_4 ≡ ∀α. α -> β 
 
-etc.
+and so on.
 
 A *box type* will be a type expression that contains exactly one free
 type variable. (You could extend this to expressions with more free variables; then you'd have
@@ -44,172 +52,332 @@ to specify which one of them the box is capturing. But let's keep it simple.) So
     (α, R) tree    (assuming R contains no free type variables)
     (α, α) tree
 
-The idea is that whatever type the free type variable α might be,
-the boxed type will be a box that "contains" an object of type `α`.
-For instance, if `α list` is our box type, and `α` is the type
-`int`, then in this context, `int list` is the type of a boxed integer.
+The idea is that whatever type the free type variable `α` might be instantiated to,
+we will have a "type box" of a certain sort that "contains" values of type `α`. For instance,
+if `α list` is our box type, and `α` instantiates to the type `int`, then in this context, `int list`
+is the type of a boxed integer.
 
-Warning: although our initial motivating examples are naturally thought of as "containers" (lists, trees, and so on, with `α`s as their "elments"), with later examples we discuss it will less intuitive to describe the box types that way. For example, where `R` is some fixed type, `R -> α` is a box type.
+Warning: although our initial motivating examples are readily thought of as "containers" (lists, trees, and so on, with `α`s as their "elements"), with later examples we discuss it will be less natural to describe the boxed types that way. For example, where `R` is some fixed type, `R -> α` will be one box type we work extensively with.
 
-The *box type* is the type `α list` (or as we might just say, `list`); the *boxed type* is some specific instantiantion of the free type variable `α`. We'll often write boxed types as a box containing the instance of the free
-type variable. So if our box type is `α list`, and `α` is instantiated with the specific type `int`, we would write:
+Also, for clarity: the *box type* is the type `α list` (or as we might just say, the `list` type operator); the *boxed type* is some specific instantiation of the free type variable `α`. We'll often write boxed types as a box containing what the free
+type variable instantiates to. So if our box type is `α list`, and `α` instantiates to the specific type `int`, we write:
 
-<u>int</u>
+<code><u>int</u></code>
 
-for the type of a boxed `int`. (We'll fool with the markup to make this a genuine box later; for now it will just display as underlined.)
+for the type of a boxed `int`.
 
 
 
-## Kleisli arrows
+## Kleisli arrows ##
 
 A lot of what we'll be doing concerns types that are called *Kleisli arrows*. Don't worry about why they're called that, or if you like go read some Category Theory. All we need to know is that these are functions whose type has the form:
 
-P -> <u>Q</u>
+<code>P -> <u>Q</u></code>
+
+That is, they are functions from values of one type `P` to a boxed type `Q`, for some choice of type expressions `P` and `Q`.
+For instance, the following are Kleisli arrow types:
+
+<code>int -> <u>bool</u></code>
+
+<code>int list -> <u>int list</u></code>
+
+In the first, `P` has become `int` and `Q` has become `bool`. (The boxed type <code><u>Q</u></code> is <code><u>bool</u></code>).
+
+Note that either of the schemas `P` or `Q` are permitted to themselves be boxed
+types. That is, if `α list` is our box type, we can write the second type as:
+
+<code><u>int</u> -> <u>int list</u></code>
 
-That is, they are functions from objects of one type `P` to a boxed type `Q`, for some choice of type expressions `P` and `Q`.
-For instance, the following are Kleisli arrows:
+And also what the rhs there is a boxing of is itself a boxed type (with the same kind of box):, so we can write it as:
 
-int -> <u>bool</u>
+<code><u>int</u> -> <span class="box2">int</span></code>
 
-int list -> <u>int list</u>
+We have to be careful though not to to unthinkingly equivocate between different kinds of boxes.
 
-In the first, `P` has become `int` and `Q` has become `bool`. (The boxed type <u>Q</u> is <u>bool</u>).
+Here are some examples of values of these Kleisli arrow types, where the box type is `α list`, and the Kleisli arrow types are <code>int -> <u>int</u></code> (that is, `int -> int list`) or <code>int -> <u>bool</u></code>:
 
-Note that the left-hand schema `P` is permitted to itself be a boxed type. That is, where
-if `α list` is our box type, we can write the second arrow as
+<pre>\x. [x]
+\x. [odd? x, odd? x]
+\x. prime_factors_of x
+\x. [0, 0, 0]</pre>
 
-<u>int</u> -> <u>Q</u>
+As semanticists, you are no doubt familiar with the debates between those who insist that propositions are sets of worlds and those who insist they are context change potentials. We hope to show you, in coming weeks, that propositions are (certain sorts of) Kleisli arrows. But this doesn't really compete with the other proposals; it is a generalization of them. Both of the other proposed structures can be construed as specific Kleisli arrow types.
 
-We'll need a number of classes of functions to help us maneuver in the
-presence of box types. We will want to define a different instance of
-each of these for whichever box type we're dealing with. (This will
-become clearly shortly.)
+
+## A family of functions for each box type ##
+
+We'll need a family of functions to help us work with box types. As will become clear, these have to be defined differently for each box type.
 
 Here are the types of our crucial functions, together with our pronunciation, and some other names the functions go by. (Usually the type doesn't fix their behavior, which will be discussed below.)
 
 <code>map (/mæp/): (P -> Q) -> <u>P</u> -> <u>Q</u></code>
 
+> In Haskell, this is the function `fmap` from the `Prelude` and `Data.Functor`; also called `<$>` in `Data.Functor` and `Control.Applicative`, and also called `Control.Applicative.liftA` and `Control.Monad.liftM`.
+
 <code>map2 (/mæptu/): (P -> Q -> R) -> <u>P</u> -> <u>Q</u> -> <u>R</u></code>
 
-<code>mid (/εmaidεnt@tI/ aka unit, return, pure): P -> <u>P</u></code>
+> In Haskell, this is called `Control.Applicative.liftA2` and `Control.Monad.liftM2`.
+
+<code>mid (/εmaidεnt@tI/): P -> <u>P</u></code>
+
+> In Haskell, this is called `Control.Monad.return` and `Control.Applicative.pure`. In other theoretical contexts it is sometimes called `unit` or `η`. In the class presentation Jim called it `𝟭`; but now we've decided that `mid` is better. (Think of it as "m" plus "identity", not as the start of "midway".) This notion is exemplified by `Just` for the box type `Maybe α` and by the singleton function for the box type `List α`.
 
 <code>m$ or mapply (/εm@plai/): <u>P -> Q</u> -> <u>P</u> -> <u>Q</u></code>
 
+> We'll use `m$` as a left-associative infix operator, reminiscent of (the right-associative) `$` which is just ordinary function application (also expressed by mere left-associative juxtaposition). In the class presentation Jim called `m$` `●`. In Haskell, it's called `Control.Monad.ap` or `Control.Applicative.<*>`.
+
 <code>&lt;=&lt; or mcomp : (Q -> <u>R</u>) -> (P -> <u>Q</u>) -> (P -> <u>R</u>)</code>
 
-<code>&gt;=&gt; or mpmoc (m-flipcomp): (P -> <u>Q</u>) -> (Q -> <u>R</u>) -> (P -> <u>R</u>)</code>
+> In Haskell, this is `Control.Monad.<=<`.
+
+<code>&gt;=&gt; (flip mcomp, should we call it mpmoc?): (P -> <u>Q</u>) -> (Q -> <u>R</u>) -> (P -> <u>R</u>)</code>
+
+> In Haskell, this is `Control.Monad.>=>`. In the class handout, we gave the types for `>=>` twice, and once was correct but the other was a typo. The above is the correct typing.
 
 <code>&gt;&gt;= or mbind : (<u>Q</u>) -> (Q -> <u>R</u>) -> (<u>R</u>)</code>
 
-<code>=&lt;&lt;mdnib (or m-flipbind) (<u>Q</u>) -> (Q -> <u>R</u>) -> (<u>R</u>)</code>
+<code>=&lt;&lt; (flip mbind, should we call it mdnib?) (Q -> <u>R</u>) -> (<u>Q</u>) -> (<u>R</u>)</code>
+
+<code>join: <span class="box2">P</span> -> <u>P</u></code>
 
-<code>join: <u>2<u>P</u></u> -> <u>P</u></code> 
+> In Haskell, this is `Control.Monad.join`. In other theoretical contexts it is sometimes called `μ`.
 
-The managerie isn't quite as bewildering as you might suppose. Many of these will
-be interdefinable. For example, here is how `mcomp` and `mbind` are related: <code>k <=< j ≡
-\a. (j a >>= k)</code>.
+Haskell uses the symbol `>>=` but calls it "bind". This is not well chosen from the perspective of formal semantics, but it's too deeply entrenched to change. We've at least preprended an "m" to the front of "bind".
 
-In most cases of interest, instances of these systems of functions will provide
-certain useful guarantees.
+Haskell's names "return" and "pure" for `mid` are even less well chosen, and we think it will be clearer in our discussion to use a different name. (Also, in other theoretical contexts this notion goes by other names, anyway, like `unit` or `η` --- having nothing to do with `η`-reduction in the Lambda Calculus.)
+
+The menagerie isn't quite as bewildering as you might suppose. Many of these will be interdefinable. For example, here is how `mcomp` and `mbind` are related: <code>k <=< j ≡ \a. (j a >>= k)</code>. We'll state some other interdefinitions below.
+
+We will move freely back and forth between using `>=>` and using `<=<` (aka `mcomp`), which
+is just `>=>` with its arguments flipped. `<=<` has the virtue that it corresponds more
+closely to the ordinary mathematical symbol `○`. But `>=>` has the virtue
+that its types flow more naturally from left to right.
+
+These functions come together in several systems, and have to be defined in a way that coheres with the other functions in the system:
 
 *   ***Mappable*** (in Haskelese, "Functors") At the most general level, box types are *Mappable*
 if there is a `map` function defined for that box type with the type given above. This
 has to obey the following Map Laws:
 
-    LAWS
+    <code>map (id : α -> α) == (id : <u>α</u> -> <u>α</u>)</code>  
+    <code>map (g ○ f) == (map g) ○ (map f)</code>
+
+    Essentially these say that `map` is a homomorphism from the algebra of `(universe α -> β, operation ○, elsment id)` to that of <code>(<u>α</u> -> <u>β</u>, ○', id')</code>, where `○'` and `id'` are `○` and `id` restricted to arguments of type <code><u>_</u></code>. That might be hard to digest because it's so abstract. Think of the following concrete example: if you take a `α list` (that's our <code><u>α</u></code>), and apply `id` to each of its elements, that's the same as applying `id` to the list itself. That's the first law. And if you apply the composition of functions `g ○ f` to each of the list's elements, that's the same as first applying `f` to each of the elements, and then going through the elements of the resulting list and applying `g` to each of those elements. That's the second law. These laws obviously hold for our familiar notion of `map` in relation to lists.
+
+    > <small>As mentioned at the top of the page, in Category Theory presentations of monads they usually talk about "endofunctors", which are mappings from a Category to itself. In the uses they make of this notion, the endofunctors combine the role of a box type <code><u>_</u></code> and of the `map` that goes together with it.</small>
+
 
 *   ***MapNable*** (in Haskelese, "Applicatives") A Mappable box type is *MapNable*
        if there are in addition `map2`, `mid`, and `mapply`.  (Given either
        of `map2` and `mapply`, you can define the other, and also `map`.
        Moreover, with `map2` in hand, `map3`, `map4`, ... `mapN` are easily definable.) These
-have to obey the following MapN Laws:
-
-
-* ***Monad*** (or "Composables") A MapNable box type is a *Monad* if there
+       have to obey the following MapN Laws:
+
+    1. <code>mid (id : P->P) : <u>P</u> -> <u>P</u></code> is a left identity for `m$`, that is: `(mid id) m$ xs = xs`
+    2. `mid (f a) = (mid f) m$ (mid a)`
+    3. The `map2`ing of composition onto boxes `fs` and `gs` of functions, when `m$`'d to a box `xs` of arguments == the `m$`ing of `fs` to the `m$`ing of `gs` to xs: `(mid (○) m$ fs m$ gs) m$ xs = fs m$ (gs m$ xs)`.
+    4. When the arguments (the right-hand operand of `m$`) are an `mid`'d value, the order of `m$`ing doesn't matter: `fs m$ (mid x) = mid ($x) m$ fs`. (Though note that it's `mid ($x)`, or `mid (\f. f x)` that gets `m$`d onto `fs`, not the original `mid x`.) Here's an example where the order *does* matter: `[succ,pred] m$ [1,2] == [2,3,0,1]`, but `[($1),($2)] m$ [succ,pred] == [2,0,3,1]`. This Law states a class of cases where the order is guaranteed not to matter.
+    5. A consequence of the laws already stated is that when the _left_-hand operand of `m$` is a `mid`'d value, the order of `m$`ing doesn't matter either: `mid f m$ xs == map (flip ($)) xs m$ mid f`.
+
+<!-- Probably there's a shorter proof, but:
+   mid T m$ xs m$ mid f
+== mid T m$ ((mid id) m$ xs) m$ mid f, by 1
+== mid (○) m$ mid T m$ mid id m$ xs m$ mid f, by 3
+== mid ($id) m$ (mid (○) m$ mid T) m$ xs m$ mid f, by 4
+== mid (○) m$ mid ($id) m$ mid (○) m$ mid T m$ xs m$ mid f, by 3
+== mid ((○) ($id)) m$ mid (○) m$ mid T m$ xs m$ mid f, by 2
+== mid ((○) ($id) (○)) m$ mid T m$ xs m$ mid f, by 2
+== mid id m$ mid T m$ xs m$ mid f, by definitions of ○ and $
+== mid T m$ xs m$ mid f, by 1
+== mid ($f) m$ (mid T m$ xs), by 4
+== mid (○) m$ mid ($f) m$ mid T m$ xs, by 3
+== mid ((○) ($f)) m$ mid T m$ xs, by 2
+== mid ((○) ($f) T) m$ xs, by 2
+== mid f m$ xs, by definitions of ○ and $ and T == flip ($)
+-->
+
+*   ***Monad*** (or "Composables") A MapNable box type is a *Monad* if there
        is in addition an associative `mcomp` having `mid` as its left and
        right identity. That is, the following Monad Laws must hold:
 
-        mcomp (mcomp j k) l (that is, (j <=< k) <=< l) = mcomp j (mcomp k l)
-        mcomp mid k (that is, mid <=< k) = k
-        mcomp k mid (that is, k <=< mid) = k
+        mcomp (mcomp j k) l (that is, (j <=< k) <=< l) == mcomp j (mcomp k l)
+        mcomp mid k (that is, mid <=< k) == k
+        mcomp k mid (that is, k <=< mid) == k
+
+    You could just as well express the Monad laws using `>=>`:
+
+        l >=> (k >=> j) == (l >=> k) >=> j
+        k >=> mid == k
+        mid >=> k == k
+
+    If you have any of `mcomp`, `mpmoc`, `mbind`, or `join`, you can use them to define the others. Also, with these functions you can define `m$` and `map2` from *MapNables*. So with Monads, all you really need to get the whole system of functions are a definition of `mid`, on the one hand, and one of `mcomp`, `mbind`, or `join`, on the other.
+
+    In practice, you will often work with `>>=`. In the Haskell manuals, they express the Monad Laws using `>>=` instead of the composition operators. This looks similar, but doesn't have the same symmetry:
+
+        u >>= (\a -> k a >>= j) == (u >>= k) >>= j
+        u >>= mid == u
+        mid a >>= k == k a
+
+     Also, Haskell calls `mid` `return` or `pure`, but we've stuck to our terminology in this context.
+
+    > <small>In Category Theory discussion, the Monad Laws are instead expressed in terms of `join` (which they call `μ`) and `mid` (which they call `η`). These are assumed to be "natural transformations" for their box type, which means that they satisfy these equations with that box type's `map`:
+    > <pre>map f ○ mid == mid ○ f<br>map f ○ join == join ○ map (map f)</pre>
+    > The Monad Laws then take the form:
+    > <pre>join ○ (map join) == join ○ join<br>join ○ mid == id == join ○ map mid</pre>
+    > The first of these says that if you have a triply-boxed type, and you first merge the inner two boxes (with `map join`), and then merge the resulting box with the outermost box, that's the same as if you had first merged the outer two boxes, and then merged the resulting box with the innermost box. The second law says that if you take a box type and wrap a second box around it (with `mid`) and then merge them, that's the same as if you had done nothing, or if you had instead wrapped a second box around each element of the original (with `map mid`, leaving the original box on the outside), and then merged them.<p>
+    > The Category Theorist would state these Laws like this, where `M` is the endofunctor that takes us from type `α` to type <code><u>α</u></code>:
+    > <pre>μ ○ M(μ) == μ ○ μ<br>μ ○ η == id == μ ○ M(η)</pre></small>
+
+
+As hinted in last week's homework and explained in class, the operations available in a Mappable system exactly preserve the "structure" of the boxed type they're operating on, and moreover are only sensitive to what content is in the corresponding original position. If you say `map f [1,2,3]`, then what ends up in the first position of the result depends only on how `f` and `1` combine.
 
-If you have any of `mcomp`, `mpmoc`, `mbind`, or `join`, you can use them to define the others.
-Also, with these functions you can define `m$` and `map2` from *MapNables*. So all you really need
-are a definition of `mid`, on the one hand, and one of `mcomp`, `mbind`, or `join`, on the other.
+For MapNable operations, on the other hand, the structure of the result may instead be a complex function of the structure of the original arguments. But only of their structure, not of their contents. And if you say `map2 f [10,20] [1,2,3]`, what ends up in the first position of the result depends only on how `f` and `10` and `1` combine.
 
-Here are some interdefinitions: TODO. Names in Haskell TODO.
+With `map`, you can supply an `f` such that `map f [3,2,0,1] == [[3,3,3],[2,2],[],[1]]`. But you can't transform `[3,2,0,1]` to `[3,3,3,2,2,1]`, and you can't do that with MapNable operations, either. That would involve the structure of the result (here, the length of the list) being sensitive to the content, and not merely the structure, of the original.
 
-## Examples
+For Monads (Composables), on the other hand, you can perform more radical transformations of that sort. For example, `join (map (\x. dup x x) [3,2,0,1])` would give us `[3,3,3,2,2,1]` (for a suitable definition of `dup`).
+
+<!--
+Some global transformations that we work with in semantics, like Veltman's test functions, can't directly be expressed in terms of the  primitive Monad operations? For example, there's no `j` such that `xs >>= j == mzero` if `xs` anywhere contains the value `1`.
+-->
+
+
+## Interdefinitions and Subsidiary notions##
+
+We said above that various of these box type operations can be defined in terms of others. Here is a list of various ways in which they're related. We try to stick to the consistent typing conventions that:
+
+<pre>
+f : α -> β;  g and h have types of the same form
+             also sometimes these will have types of the form α -> β -> γ
+             note that α and β are permitted to be, but needn't be, boxed types
+j : α -> <u>β</u>; k and l have types of the same form
+u : <u>α</u>;      v and xs and ys have types of the same form
+
+w : <span class="box2">α</span>
+</pre>
+
+But we may sometimes slip.
+
+Here are some ways the different notions are related:
+
+<pre>
+j >=> k ≡= \a. (j a >>= k)
+u >>= k == (id >=> k) u; or ((\(). u) >=> k) ()
+u >>= k == join (map k u)
+join w == w >>= id
+map2 f xs ys == xs >>= (\x. ys >>= (\y. mid (f x y)))
+map2 f xs ys == (map f xs) m$ ys, using m$ as an infix operator
+fs m$ xs == fs >>= (\f. map f xs)
+m$ == map2 id
+map f xs == mid f m$ xs
+map f u == u >>= mid ○ f
+</pre>
+
+
+Here are some other monadic notion that you may sometimes encounter:
+
+* <code>mzero</code> is a value of type <code><u>α</u></code> that is exemplified by `Nothing` for the box type `Maybe α` and by `[]` for the box type `List α`. It has the behavior that `anything m$ mzero == mzero == mzero m$ anything == mzero >>= anything`. In Haskell, this notion is called `Control.Applicative.empty` or `Control.Monad.mzero`.
+
+* Haskell has a notion `>>` definable as `\u v. map (const id) u m$ v`, or as `\u v. u >>= const v`. This is often useful, and `u >> v` won't in general be identical to just `v`. For example, using the box type `List α`, `[1,2,3] >> [4,5] == [4,5,4,5,4,5]`. But in the special case of `mzero`, it is a consequence of what we said above that `anything >> mzero == mzero`. Haskell also calls `>>` `Control.Applicative.*>`.
+
+* Haskell has a correlative notion `Control.Applicative.<*`, definable as `\u v. map const u m$ v`. For example, `[1,2,3] <* [4,5] == [1,1,2,2,3,3]`. You might expect Haskell to call `<*` `<<`, but they don't. They used to use `<<` for `flip (>>)` instead, but now they seem not to use `<<` anymore.
+
+* <code>mapconst</code> is definable as `map ○ const`. For example `mapconst 4 [1,2,3] == [4,4,4]`. Haskell calls `mapconst` `<$` in `Data.Functor` and `Control.Applicative`. They also use `$>` for `flip mapconst`, and `Control.Monad.void` for `mapconst ()`.
+
+
+
+## Examples ##
 
 To take a trivial (but, as we will see, still useful) example,
-consider the identity box type Id: `α`. So if `α` is type `bool`,
-then a boxed `α` is ... a `bool`. In terms of the box analogy, the
-Identity box type is a completely invisible box. With the following
-definitions
+consider the Identity box type: `α`. So if `α` is type `bool`,
+then a boxed `α` is ... a `bool`. That is, <code><u>α</u> == α</code>.
+In terms of the box analogy, the Identity box type is a completely invisible box. With the following
+definitions:
 
-    mid ≡ \p. p
-    mcomp ≡ \f g x.f (g x)
+    mid ≡ \p. p, that is, our familiar combinator I
+    mcomp ≡ \f g x. f (g x), that is, ordinary function composition (○) (aka the B combinator)
 
 Identity is a monad.  Here is a demonstration that the laws hold:
 
-    mcomp mid k == (\fgx.f(gx)) (\p.p) k
-                ~~> \x.(\p.p)(kx)
-                ~~> \x.kx
-                ~~> k
-    mcomp k mid == (\fgx.f(gx)) k (\p.p)
-                ~~> \x.k((\p.p)x)
-                ~~> \x.kx
-                ~~> k
-    mcomp (mcomp j k) l == mcomp ((\fgx.f(gx)) j k) l
-                       ~~> mcomp (\x.j(kx)) l
-                        == (\fgx.f(gx)) (\x.j(kx)) l
-                       ~~> \x.(\x.j(kx))(lx)
-                       ~~> \x.j(k(lx))
-    mcomp j (mcomp k l) == mcomp j ((\fgx.f(gx)) k l)
-                       ~~> mcomp j (\x.k(lx))
-                        == (\fgx.f(gx)) j (\x.k(lx))
-                       ~~> \x.j((\x.k(lx)) x)
-                       ~~> \x.j(k(lx))
-
-Id is the favorite monad of mimes.
+    mcomp mid k  (\fgx.f(gx)) (\p.p) k
+              ~~> \x.(\p.p)(kx)
+              ~~> \x.kx
+              ~~> k
+    mcomp k mid  (\fgx.f(gx)) k (\p.p)
+              ~~> \x.k((\p.p)x)
+              ~~> \x.kx
+              ~~> k
+    mcomp (mcomp j k) l  mcomp ((\fgx.f(gx)) j k) l
+                      ~~> mcomp (\x.j(kx)) l
+                         (\fgx.f(gx)) (\x.j(kx)) l
+                      ~~> \x.(\x.j(kx))(lx)
+                      ~~> \x.j(k(lx))
+    mcomp j (mcomp k l)  mcomp j ((\fgx.f(gx)) k l)
+                      ~~> mcomp j (\x.k(lx))
+                         (\fgx.f(gx)) j (\x.k(lx))
+                      ~~> \x.j((\x.k(lx)) x)
+                      ~~> \x.j(k(lx))
+
+The Identity monad is favored by mimes.
 
 To take a slightly less trivial (and even more useful) example,
 consider the box type `α list`, with the following operations:
 
-    mid: α -> [α]
+    mid : α -> [α]
     mid a = [a]
  
-    mcomp: (β -> [γ]) -> (α -> [β]) -> (α -> [γ])
-    mcomp f g a = concat (map f (g a))
-                = foldr (\b -> \gs -> (f b) ++ gs) [] (g a) 
-                = [c | b <- g a, c <- f b]
+    mcomp : (β -> [γ]) -> (α -> [β]) -> (α -> [γ])
+    mcomp k j a = concat (map k (j a)) = List.flatten (List.map k (j a))
+                = foldr (\b ks -> (k b) ++ ks) [] (j a) = List.fold_right (fun b ks -> List.append (k b) ks) [] (j a)
+                = [c | b <- j a, c <- k b]
 
-These three definitions of `mcomp` are all equivalent, and it is easy to see that they obey the monad laws (see exercises).
+In the first two definitions of `mcomp`, we give the definition first in Haskell and then in the equivalent OCaml. The three different definitions of `mcomp` (one for each line) are all equivalent, and it is easy to show that they obey the Monad Laws. (You will do this in the homework.)
 
-In words, `mcomp f g a` feeds the `a` (which has type `α`) to `g`, which returns a list of `β`s;
-each `β` in that list is fed to `f`, which returns a list of `γ`s. The
+In words, `mcomp k j a` feeds the `a` (which has type `α`) to `j`, which returns a list of `β`s;
+each `β` in that list is fed to `k`, which returns a list of `γ`s. The
 final result is the concatenation of those lists of `γ`s.
 
 For example: 
 
-    let f b = [b, b+1] in
-    let g a = [a*a, a+a] in
-    mcomp f g 7 ==> [49, 50, 14, 15]
+    let j a = [a*a, a+a] in
+    let k b = [b, b+1] in
+    mcomp k j 7 ==> [49, 50, 14, 15]
 
-`g 7` produced `[49, 14]`, which after being fed through `f` gave us `[49, 50, 14, 15]`.
+`j 7` produced `[49, 14]`, which after being fed through `k` gave us `[49, 50, 14, 15]`.
 
-Contrast that to `m$` (`mapply`, which operates not on two *box-producing functions*, but instead on two *values of a boxed type*, one containing functions to be applied to the values in the other box, via some predefined scheme. Thus:
+Contrast that to `m$` (`mapply`), which operates not on two *box-producing functions*, but instead on two *values of a boxed type*, one containing functions to be applied to the values in the other box, via some predefined scheme. Thus:
 
-    let gs = [(\a->a*a),(\a->a+a)] in
+    let js = [(\a->a*a),(\a->a+a)] in
     let xs = [7, 5] in
-    mapply gs xs ==> [49, 25, 14, 10]
+    mapply js xs ==> [49, 25, 14, 10]
+
+
+The question came up in class of when box types might fail to be Mappable, or Mappables might fail to be MapNables, or MapNables might fail to be Monads.
+
+For the first failure, we noted that it's easy to define a `map` operation for the box type `R -> α`, for a fixed type `R`. You `map` a function of type `P -> Q` over a value of the boxed type <code><u>P</u></code>, that is `R -> P`, by just returning a function that takes some `R` as input, first supplies it to your `R -> P` value, and then supplies the result to your `map`ped function of type `P -> Q`. (We will be working with this Mappable extensively; in fact it's not just a Mappable but more specifically a Monad.)
+
+But if on the other hand, your box type is `α -> R`, you'll find that there is no way to define a `map` operation that takes arbitrary functions of type `P -> Q` and values of the boxed type <code><u>P</u></code>, that is `P -> R`, and returns values of the boxed type <code><u>Q</u></code>.
+
+For the second failure, that is cases of Mappables that are not MapNables, we cited box types like `(R, α)`, for arbitrary fixed types `R`. The `map` operation for these is defined by `map f (r,a) = (r, f a)`. For certain choices of `R` these can be MapNables too. The easiest case is when `R` is the type of `()`. But when we look at the MapNable Laws, we'll see that they impose constraints we cannot satisfy for *every* choice of the fixed type `R`. Here's why. We'll need to define `mid a = (r0, a)` for some specific `r0` of type `R`. Then the MapNable Laws will entail:
 
+    1. (r0,id) m$ (r,x) == (r,x)
+    2. (r0,f x) == (r0,f) m$ (r0,x)
+    3. (r0,(○)) m$ (r'',f) m$ (r',g) m$ (r,x) == (r'',f) m$ ((r',g) m$ (r,x))
+    4. (r'',f) m$ (r0,x) == (r0,($x)) m$ (r'',f)
+    5. (r0,f) m$ (r,x) == (r,($x)) m$ (r0,f)
 
-As we illustrated in class, there are clear patterns shared between lists and option types and trees, so perhaps you can see why people want to identify the general structures. But it probably isn't obvious yet why it would be useful to do so. To a large extent, this will only emerge over the next few classes. But we'll begin to demonstrate the usefulness of these patterns by talking through a simple example, that uses the Monadic functions of the Option/Maybe box type.
+Now we are not going to be able to write a `m$` function that inspects the second element of its left-hand operand to check if it's the `id` function; the identity of functions is not decidable. So the only way to satisfy Law 1 will be to use the first element of the right-hand operand (`r`) at least in those cases when the first element of the left-hand operand is `r0`. But then that means that the result of the lhs of Law 5 will also have a first element of `r`; so, turning now to the rhs of Law 5, we see that `m$` must use the first element of its _left_-hand operand (here again `r`) at least in those cases when the first element of its right-hand operand is `r0`. If our `R` type has a natural *monoid* structure, we could just let `r0` be the monoid's identity, and have `m$` combine other `R`s using the monoid's operation. Alternatively, if the `R` type is one that we can safely apply the predicate `(r0==)` to, then we could define `m$` something like this:
 
+    let (m$) (r1,f) (r2,x) = ((if r0==r1 then r2 else if r0==r2 then r1 else ...), ...)
 
-Safe division
--------------
+But for some types neither of these will be the case. For function types, as we already mentioned, `==` is not decidable. If the functions have suitable types, they do form a monoid with `○` as the operation and `id` as the identity; but many function types won't be such that arbitrary functions of that type are composable. So when `R` is the type of functions from `int`s to `bool`s, for example, we won't have any way to write a `m$` that satisfies the constraints stated above.
+
+For the third failure, that is examples of MapNables that aren't Monads, we'll just state that lists where the `map2` operation is taken to be zipping rather than taking the Cartesian product (what in Haskell are called `ZipList`s), these are claimed to exemplify that failure. But we aren't now in a position to demonstrate that to you.
+
+
+## Safe division ##
+
+As we discussed in class, there are clear patterns shared between lists and option types and trees, so perhaps you can see why people want to figure out the general structures. But it probably isn't obvious yet why it would be useful to do so. To a large extent, this will only emerge over the next few classes. But we'll begin to demonstrate the usefulness of these patterns by talking through a simple example, that uses the monadic functions of the Option/Maybe box type.
 
 Integer division presupposes that its second argument
 (the divisor) is not zero, upon pain of presupposition failure.
@@ -244,14 +412,13 @@ val safe_div : int -> int -> int option = fun
 # safe_div 12 0;;
 - : int option = None
 # safe_div (safe_div 12 2) 3;;
-# safe_div (safe_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,
+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:
@@ -259,10 +426,11 @@ operations. So we have to jack up the types of the inputs:
 <pre>
 let safe_div2 (u:int option) (v:int option) =
   match u with
-         None -> None
-       | Some x -> (match v with
-                                 Some 0 -> None
-                               | Some y -> Some (x / y));;
+  | None -> None
+  | Some x ->
+      (match v with
+      | Some 0 -> None
+      | Some y -> Some (x / y));;
 
 (*
 val safe_div2 : int option -> int option -> int option = <fun>
@@ -275,8 +443,8 @@ val safe_div2 : int option -> int option -> int option = <fun>
 *)
 </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.
+Calling the function now involves some extra verbosity, but it gives us what we need: now we can try to divide by anything we
+want, without fear that we're going to trigger system errors.
 
 I prefer to line up the `match` alternatives by using OCaml's
 built-in tuple type:
@@ -284,15 +452,15 @@ built-in tuple type:
 <pre>
 let safe_div2 (u:int option) (v:int option) =
   match (u, v) with
-    | (None, _) -> None
-    | (_, None) -> None
-    | (_, Some 0) -> None
-    | (Some x, Some y) -> Some (x / y);;
+  | (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
+aware of the possibility that one of their arguments has already triggered a
 presupposition failure:
 
 <pre>
@@ -315,42 +483,36 @@ This works, but is somewhat disappointing: the `safe_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, and other functional programming languages, is to use the monadic
-`bind` operator, `>>=`. (The name "bind" is not well chosen from our
-perspective, but this is too deeply entrenched by now.) As mentioned above,
-there needs to be a different `>>=` operator for each Monad or box type you're working with.
+But we can automate the adjustment, using the monadic machinery we introduced above.
+As we said, there needs to be different `>>=`, `map2` and so on operations for each
+monad or box type we're working with.
 Haskell finesses this by "overloading" the single symbol `>>=`; you can just input that
 symbol and it will calculate from the context of the surrounding type constraints what
-monad you must have meant. In OCaml, the `>>=` or `bind` operator is not pre-defined, but we will
+monad you must have meant. In OCaml, the monadic operators are not pre-defined, but we will
 give you a library that has definitions for all the standard monads, as in Haskell.
-For now, though, we will define our `bind` operation by hand:
+For now, though, we will define our `>>=` and `map2` operations by hand:
 
 <pre>
-let bind (u: int option) (f: int -> (int option)) =
+let (>>=) (u : 'a option) (j : 'a -> 'b option) : 'b option =
   match u with
-    |  None -> None
-    | Some x -> f x;;
+    | None -> None
+    | Some x -> j x;;
 
-let safe_add3 (u: int option) (v: int option) =
-  bind u (fun x -> bind v (fun y -> Some (x + y)));;
+let map2 (f : 'a -> 'b -> 'c) (u : 'a option) (v : 'b option) : 'c option =
+  u >>= (fun x -> v >>= (fun y -> Some (f x y)));;
 
-(* This is really just `map2 (+)`, using the `map2` operation that corresponds to
-   definition of `bind`. *)
+let safe_add3 = map2 (+);;    (* that was easy *)
 
 let safe_div3 (u: int option) (v: int option) =
-  bind u (fun x -> bind v (fun y -> if 0 = y then None else Some (x / y)));;
-
-(* This goes back to some of the simplicity of the original safe_div, without the complexity
-   introduced by safe_div2. *)
+  u >>= (fun x -> v >>= (fun y -> if 0 = y then None else Some (x / y)));;
 </pre>
 
-The above definitions look even simpler if you focus on the fact that `safe_add3` can be written as simply `map2 (+)`, and that `safe_div3` could be written as `u >>= fun x -> v >>= fun y -> if 0 = y then None else Some (x / y)`. Haskell has an even more user-friendly notation for this, namely:
+Haskell has an even more user-friendly notation for defining `safe_div3`, namely:
 
     safe_div3 :: Maybe Int -> Maybe Int -> Maybe Int
     safe_div3 u v = do {x <- u;
                         y <- v;
-                        if 0 == y then Nothing else return (x `div` y)}
+                        if 0 == y then Nothing else Just (x `div` y)}
 
 Let's see our new functions in action:
 
@@ -369,12 +531,13 @@ Compare the new definitions of `safe_add3` and `safe_div3` closely: the definiti
 for `safe_add3` shows what it looks like to equip an ordinary operation to
 survive in dangerous presupposition-filled world. Note that the new
 definition of `safe_add3` does not need to test whether its arguments are
-None objects or real numbers---those details are hidden inside of the
+`None` values or real numbers---those details are hidden inside of the
 `bind` function.
 
-The definition of `safe_div3` shows exactly what extra needs to be said in
-order to trigger the no-division-by-zero presupposition. Here, too, we don't
-need to keep track of what presuppositions may have already failed
+Note also that our definition of `safe_div3` recovers some of the simplicity of
+the original `safe_div`, without the complexity introduced by `safe_div2`. We now
+add exactly what extra is needed to track the no-division-by-zero presupposition. Here, too, we don't
+need to keep track of what other presuppositions may have already failed
 for whatever reason on our inputs.
 
 (Linguistics note: Dividing by zero is supposed to feel like a kind of
@@ -390,5 +553,5 @@ theory of accommodation, and a theory of the situations in which
 material within the sentence can satisfy presuppositions for other
 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.)
+sophisticated techniques than the super-simple Option/Maybe monad.)