towards monads: tweak error message
[lambda.git] / damn.mdwn
index 8bbe724..ad68775 100644 (file)
--- a/damn.mdwn
+++ b/damn.mdwn
@@ -1,3 +1,20 @@
+1.     Sentences have truth conditions.
+
+2.     If "John read the book" is true, then it follows that:
+       John read something,  
+       Someone read the book,  
+       John did something to the book,  
+       etc.
+
+3. If "John read the damn book",
+   all the same entailments follow.
+   To a first approximation, "damn" does not affect at-issue truth
+   conditions.  
+
+4. "Damn" does contribute information about the attitude of the speaker
+   towards some aspect of the situation described by the sentence.
+
+
 Expressives such as "damn" have side effects that don't affect the
 at-issue value of the sentence in which they occur.  What this claim
 says is unpacked at some length here: <http://tinyurl.com/cbarker/salt/interaction/salt.pdf>.
@@ -43,7 +60,7 @@ What's going on here?
 ---------------------
 
 `(cons M N)` is a request to build an ordered pair out of the values M and N.
-Scheme displays that pair as `'(M . N)` You can't write `(M . N)` yourself and expect Scheme to understand that you're talking about this pair. If you tried, to, Scheme would think you're trying to apply the function M to some arguments, which you're not, and also
+Scheme displays that pair as `'(M . N)` You can't write `(M . N)` yourself and expect Scheme to understand that you're talking about this pair. If you tried to, Scheme would think you're trying to apply the function M to some arguments, which you're not, and also
 Scheme would be confused by what argument the `.` is supposed to be. So, you say:
 
        (cons M N)
@@ -56,7 +73,7 @@ You *can* write `'(M . N)` (with the prefixed single quote), and Scheme will und
 
 There is an underlying reason why parentheses are used both when displaying the ordered pair, and also to mean "apply this function to these arguments." However, at this point, you may well see this as a confusing overloading of parentheses to fill different syntactic roles.
 
-Now what about the elements of our ordered pairs. Why do we say `(cons 'the 'man)`. Why are those single quotes there? Well, if you just said `(cons the man)`, Scheme would understand `the` and `man` to be variables, and it would complain that you hadn't bound these variables to any values. We don't want to build an ordered pair out of the values possessed by variables `the` and `man`. Instead, we want to just make up some primitive value THE to stand for the meaning of an object-language determiner, and some primitive value MAN to stand for the meaning of an object-language noun phrase. The notation `'the` is Scheme's way of designating a primitive atomic value. Note there is no closing single quote, only a prefixed one. Scheme calls these primitive atomic values "symbols." That term is a bit misleading, because the symbol `'the` is not the same as the variable `the`. Neither is it the same as what's called the string `"the"`. The latter is a structured value, composed out of three character values. The symbol `'the`, on the other hand, is an atomic value. It has no parts. (The notation the programmer uses to designate this atomic value has four characters, but the value designated itself has no parts.) If you think this is all somewhat confusing, you're right. It gets easier with practice.
+Now what about the elements of our ordered pairs. Why do we say `(cons 'the 'man)`. Why are those single quotes there? Well, if you just said `(cons the man)`, Scheme would understand `the` and `man` to be variables, and it would complain that you hadn't bound these variables to any values. We don't want to build an ordered pair out of the values possessed by variables `the` and `man`. Instead, we want to just make up some primitive value THE to stand for the meaning of an object-language determiner, and some primitive value MAN to stand for the meaning of an object-language noun. The notation `'the` is Scheme's way of designating a primitive atomic value. Note there is no closing single quote, only a prefixed one. Scheme calls these primitive atomic values "symbols." That term is a bit misleading, because the symbol `'the` is not the same as the variable `the`. Neither is it the same as what's called the string `"the"`. The latter is a structured value, composed out of three character values. The symbol `'the`, on the other hand, is an atomic value. It has no parts. (The notation the programmer uses to designate this atomic value has four characters, but the value designated itself has no parts.) If you think this is all somewhat confusing, you're right. It gets easier with practice.
 
 `'the` can also be written `(quote the)`. This is even more confusing, because here the `the` is not interpreted as a variable. (Try `(let* ((the 3)) (quote the))`.) If you come across `(quote the)`, just read it as a verbose (and perhaps misleading) way of writing `'the`, not as the application of any function to any value.
 
@@ -126,7 +143,7 @@ Now we can say:
 
 and we get back:
 
-       ((the . man) . (read . (the . (id . book))))
+       '((the . man) . (read . (the . (id . book))))
 
 ---or an equivalent shorthand. (I'm now going to stop saying this.)
 
@@ -149,7 +166,7 @@ But then:
 
 gives us:
 
-       ((the . man) . (read . (the . (bad . book))))
+       '((the . man) . (read . (the . (bad . book))))
 
 Which is not quite what we're looking for. We don't want to contribute the normal adjectival meaning of "bad" to the proposition asserted. Instead we want badness to be a side-issue linguistic contribution. We might try:
 
@@ -157,9 +174,9 @@ Which is not quite what we're looking for. We don't want to contribute the norma
 
 But then we'd get:
 
-       ((the . man) . (read . (the . ((side-effect . bad) . book))))
+       '((the . man) . (read . (the . ((side-effect . bad) . book))))
 
-and we said at the outset that the context `(the . ( ... . book))` shouldn't need to know how to interact with affective meanings. That's precisely the problem we're trying to solve.
+and we said at the outset that the context `(the . (<> . book))` shouldn't need to know how to interact with affective meanings. (I'll use `<>` to indicate a "hole" in a larger expression.)
 
 
 Let's use continuations
@@ -167,7 +184,7 @@ Let's use continuations
 
 A promising way to handle this is with **continuations**, which you will get much more familiar with as this seminar progresses. Don't worry about not understanding what's going on quite yet. This is just an advertisement that's supposed to provoke your imagination.
 
-Chris and others have applied the apparatus of continuations to the analysis of expressives in the paper cited at the top. For a simple in-class demonstration, we tried to do the following.
+Chris and others have applied the apparatus of continuations to the analysis of expressives in the paper cited at the top. For a simple in-class demonstration, here's what we tried to do.
 
        (call/cc (lambda (k) ...))
 
@@ -193,14 +210,14 @@ What happens then when we evaluate:
 We get something like this:
 
 <blockquote>
-<strong>"bad"</strong> ((the . man) . (read . (the . (id . book))))
+<strong>"bad"</strong> '((the . man) . (read . (the . (id . book))))
 </blockquote>
 
-Yay! The affective meaning has jumped out of the compositional evaluation of the main sentence, and the context `(the . (... . book))` only has to deal with the trivial adjectival meaning `'id`.
+Yay! The affective meaning has jumped out of the compositional evaluation of the main sentence, and the context `(the . (<> . book))` only has to deal with the trivial adjectival meaning `'id`.
 
 
-But
----
+But...
+------
 
 As came out in discussion, the `print` we're using here already constitutes a kind of side-effect mechanism of its own. If you say:
 
@@ -208,15 +225,17 @@ As came out in discussion, the `print` we're using here already constitutes a ki
 
 and then ask for the evaluation of:
 
-       (+ 2 (three-thunk))
+       (+ (+ 2 (three-thunk)) 1)
 
 you'll see something like:
 
 <blockquote>
-<strong>"hi"</strong> 5
+<strong>"hi"</strong> 6
 </blockquote>
 
-So the demonstration we tried in class was pedagogically flawed. It didn't properly display how continuations are a minimally effective apparatus for representing affective meaning. In fact, continuations were still doing the work, but it wasn't the explicit continuations we were writing out for you. It was instead continuations implicit in the `print` operation.
+In other words, the printing of "hi" already happens on the side, outside of the main evaluation. Continuations don't need to be explicitly invoked.
+
+So the demonstration we tried in class was pedagogically flawed. It didn't properly display how continuations are a minimally effective apparatus for representing affective meaning. In fact, continuations *were* still doing the work, but it wasn't the explicit continuations we were writing out for you. It was instead continuations implicit in the `print` operation.
 
 So a better demonstration would do without any device like `print` that already incorporates continuations implicitly. Any continuation-manipulation should be fully explicit.
 
@@ -226,7 +245,7 @@ Can we do better?
 
 Instead of representing the side-issue affective contribution by printing "bad", let's instead try to build a pair of side-effect contributions and at-issue assertion. Then what we want would be something like:
 
-       ((side-effect . bad) . ((the . man) . (read . (the . (id . book)))))
+       '((side-effect . bad) . ((the . man) . (read . (the . (id . book)))))
 
 Only we want to get this from the evaluation of:
 
@@ -246,12 +265,12 @@ It's not immediately clear how to do it with "undelimited" continuations, of the
        (define damn (lambda () (call/cc (lambda (k) (cons (cons 'side-effect 'bad) (k 'id))))))
 
 
-The idea here is we capture the continuation that the thunk `(damn)` has when it gets evaluated. This continuation is bound to the variable `k`. We supply `'id` as an argument to that continuation. When the main, at-issue tree is all built, then we return a pair `((side-effect bad) AT-ISSUE-TREE)`.
+The idea here is we capture the continuation that `(damn)` has when it gets evaluated. This continuation is bound to the variable `k`. We supply `'id` as an argument to that continuation. When the main, at-issue tree is all built, then we return a pair `'((side-effect . bad) . AT-ISSUE-TREE)`.
 
-However, this doesn't work. The reason is that an undelimited continuation represents the future of the evaluation of `(damn)` *until the end of the computation*. So when `'id` is supplied to `k`, we go back to building the at-issue tree until we're finished *and that's the end of the computation*. We never get to go back and evaluate the context `(cons (cons 'side-effect 'bad) ...)`.
+However, this doesn't work. The reason is that an undelimited continuation represents the future of the evaluation of `(damn)` *until the end of the computation*. So when `'id` is supplied to `k`, we go back to building the at-issue tree until we're finished *and that's the end of the computation*. We never get to go back and evaluate the application of `(cons (cons 'side-effect 'bad) <>)` to anything.
 
 
-With undelimited continuations
+With delimited continuations
 ------------------------------
 
 The straightforward way to fix this is to use, not undelimited continuations, but instead a more powerful apparatus called "delimited continuations." These too will be explained in due course, don't expect to understand all this now.
@@ -268,12 +287,14 @@ but the behavior is the same. It's just that now our continuation doesn't stretc
 
        (reset ...)
 
-This is a kind of continuation-scope-marker. There are some interesting default behaviors if you don't explicitly specify where the limits are. But we'll be fully explicit here.
+This is a kind of continuation-scope-marker. There are some interesting default behaviors if you don't explicitly specify where the limits are. In fact, in the interactive interpreter we wouldn't need to ever explicitly mark the scopes. They'd by default be just where we want them to be. But we'll be fully explicit here.
 
 If a block `...` never invokes a shift, then `(reset ...)` will evaluate just the same as `...`. So for uniformity, we can designate our continuation-scopes even on computations that don't capture and manipulate continuations.
 
 Going back to the beginning, then. We start with:
 
+       (require racket/control) ; this tells Scheme to let us use shift and reset
+
        (define damn (lambda () 'id))
 
 We evaluate:
@@ -284,29 +305,28 @@ We evaluate:
                                          (cons (damn) 
                                                'book)))))
 
-Remember, the reset isn't actually *doing* anything. It's not a function that's taking the other material as an argument. It's instead a scope-marker. Here it's not even needed (and in fact in the interactive interpreter, it wouldn't even be needed when we invoke continuations, because of the default position it takes).  But we're inserting it to be explicit and uniform.
+Remember, the reset isn't actually *doing* anything. It's not a function that's taking the other material as an argument. It's instead a scope-marker. Here it's not even needed; but we're inserting it anyway to be explicit and uniform.
 
 Evaluating that gives us:
 
-       ((the . man) . (read . (the . (id . book))))
+       '((the . man) . (read . (the . (id . book))))
 
 
 Now to pair that with an affective side-issue content, we'd instead define `damn` as:
 
-       (require racket/control) ; this tells Scheme to let us use shift and reset
        (define damn (lambda () (shift k (cons (cons 'side-effect 'bad) (k 'id)))))
 
-And voila:
+And voil&agrave;!
 
-(reset (cons (cons 'the 'man) 
-      (cons 'read
-            (cons 'the
-                  (cons (damn) 
-                        'book)))))
+       (reset (cons (cons 'the 'man) 
+                 (cons 'read
+                               (cons 'the
+                                         (cons (damn) 
+                                                       'book)))))
 
 evaluates to:
 
-       ((side-effect bad) ((the . man) . (read . (the . (id . book)))))
+       '((side-effect . bad) ((the . man) . (read . (the . (id . book)))))
 
 So that's the straightforward way of repairing the strategy we used in class, without using `print`. We also have to switch to using delimited continuations.
 
@@ -316,104 +336,17 @@ Ken's proposal
 
 Ken Shan pointed out a lovely way to get to the same end-point still using only undelimited continuations (`call/cc`).
 
-(let ((pragma
-       ; An ordered pair whose first component is the assertion
-       ; operator, a unary function, and whose second component
-       ; is the meaning of "damn", a thunk.
-       (call/cc (lambda (k)
-          (cons (lambda (p) p)
-                (lambda () (k (cons (lambda (p) (cons (cons 'side-effect 'bad) p))
-                                    (lambda () 'id)))))))))
-  (let ((assert (car pragma)) ; this binds assert to the first element of the pair pragma
-        (damn   (cdr pragma))) ; this binds damn to the second element of the pair pragma
-    (assert (cons (cons 'the 'student) (cons 'read (cons 'the (cons (damn) 'book)))))))
-
-We won't do much to explain this. We'll just leave it for you to chew on.
-
-
-
-
-       #lang racket
-       ;(define damn (lambda () 'id))
-       (define damn (lambda () (call/cc (lambda (k) 
-                                                                         ; (k 'id)
-                                                                          (print "Something's bad")
-                                                                          (k 'id)
-                                                                          ))))
-
-       (list (list 'the (list (damn) 'man))
-                 (list 'read 
-                               (list 'the (list (damn) 'book))))
-
-
-
-
-
-       #lang racket
-       (require racket/control)
-
-       (define damn0 (lambda ()
-                                       'id))
-
-       (define damn1 (lambda ()
-                                       (cons '("side effect" bad)
-                                                 'id)))
-
-       (define damn2 (lambda () (shift k
-                                                                       (cons '("side effect" bad) 
-                                                                                 (list (k 'id))))))
-
-       (define damn3 (lambda () (shift k
-                                                                       (list (k 'id)
-                                                                                 '("side effect" bad)))))
-
-
-; Now if we use damn0, our compositional semantics will work OK but
-; we don't yet have any affective contribution:
-
-       (list "main content" 'i (list 'like (list 'the (damn0) 'boy)))
-       ; '("main content" i (like (the id boy)))
-
-
-; If we use damn1, we've added in the affective side effect:
-
-       (list "main content" 'i (list 'like (list 'the (damn1) 'boy)))
-       ; '("main content" i (like (the (("side effect" bad) . id) boy)))
-
-; However, the context (list 'the ... 'boy) is now being asked to operate
-; on an element (("side effect" bad) . id), and it may complain it doesn't
-; know what that is. It knows how to use 'id to get (list 'the 'id 'boy),
-; and how to use 'bad to get (list 'the 'bad 'boy), but we're supposed to
-; have something different here.
-
-; To get what we want we need to use (delimited) continuations:
-       (reset (list "main content" 'i (list 'like (list 'the (damn2) 'boy))))
-       ; '(("side effect" bad) ("main content" i (like (the id boy))))
-
-; or to get the side effect at the end:
-
-       (reset (list "main content" 'i (list 'like (list 'the (damn3) 'boy))))
-       ; '(("main content" i (like (the id boy))) ("side effect" bad))
-
-; If you're working in the interactive interpreter, the outermost "reset" here
-; is already in its default position, so it doesn't need to be explicitly
-; specified:
-
-       (list "main content" 'i (list 'like (list 'the (damn2) 'boy)))
-       ; '(("side effect" bad) ("main content" i (like (the id boy))))
-
-; However, if you're executing this as a file, you would need to include explicit resets.
-
-
-
-; Instead of using reset/shift you could use an element like "print" in
-; building the side effect, as we did in class. Here you wouldn't require an
-; explicit continuation, but as Chris said, that's because "print" already
-; represents an implicit continuation.
-
-       (define damn4 (lambda () (begin (print "bad") 'id)))
-       (list "main content" 'i (list 'like (list 'the (damn4) 'boy)))
-       ; "bad"'("main content" i (like (the id boy)))
-;
-
+       (let ((pragma
+                  ; An ordered pair whose first component is the assertion
+                  ; operator, a unary function, and whose second component
+                  ; is the meaning of "damn", a thunk.
+                  (call/cc (lambda (k)
+                         (cons (lambda (p) p)
+                                       (lambda () (k (cons (lambda (p) (cons (cons 'side-effect 'bad) p))
+                                                                               (lambda () 'id)))))))))
+         (let ((assert (car pragma)) ; this binds assert to the first element of the pair pragma
+                       (damn   (cdr pragma))) ; this binds damn to the second element of the pair pragma
+               (assert (cons (cons 'the 'man) (cons 'read (cons 'the (cons (damn) 'book)))))))
+
+We won't do much to explain this. We'll just leave it for you to digest, perhaps later in the course. When you succeed in doing so, you will be as delighted by it as we are.