0b1f1f31339fe44233b6bd655a56f0eb82eec1cc
[lambda.git] / damn.mdwn
1 Expressives such as "damn" have side effects that don't affect the
2 at-issue value of the sentence in which they occur.  What this claim
3 says is unpacked at some length here: <http://tinyurl.com/cbarker/salt/interaction/salt.pdf>.
4
5 <!--
6 Chris also emailed me this paper, may this be publicly posted?
7 <http://tinyurl.com/cbarker/salt/interaction/salt.pdf>
8 -->
9
10
11 In brief, "The man read the damn book" means the same thing as "The
12 man read the book" as far as what must be the case in the world for
13 the sentence to be true.  However, the sentence with the "damn" in it
14 in addition conveys the claim that something about the described
15 situtation is not as it should be.  (The person who is committed to
16 that claim is whoever utters the sentence.)
17
18 So we need a way of evaluating sentences that allows "damn" to launch
19 a side effect without affecting the truth conditions of the sentence
20 in which it occurs.
21
22 Furthermore, we don't want to change the meaning of "the", "man",
23 "read", or "book"---those elements are completely innocent, and
24 shouldn't be burdened with helping compute affective content.
25
26
27 Some nice things: we can remove one or both of the damns, or add more,
28 and everything works.  As desired, the rest of the words don't need to
29 know anything about side effects.
30
31 Some of the complexities:
32
33 Because the compositional semantics doesn't know about words that
34 denote functions, "damn" contributes a trivial adjectival meaning
35 (here, the identity function 'id) to the composition.
36
37
38
39 What we did in Monday's seminar:
40
41 We start with a simulation of semantic composition:
42
43         (cons (cons 'the 'man) 
44                   (cons 'read
45                                 (cons 'the
46                                           'book)))
47
48 ; evaluates to ((the . man) . (read . (the . book)))
49
50 `(cons M N)` is a request to build an ordered pair out of the values M and N.
51 Scheme displays that pair as `(M . N)` You can't write the pair that way yourself:
52 if you tried to, Scheme would think you're trying to apply the function M to some arguments, which you're not, and also
53 Scheme would be confused by what argument the `.` is supposed to be. So, you say:
54         (cons M N)
55 and that evaluates to an ordered pair, and Scheme displays that ordered pair as
56         (M . N)
57 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.
58
59 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 dummy value THE to stand for the meaning of an object-language determiner, and some dummy value MAN to stand for the meaning of an object-language noun phrase. The notation `'the` is Scheme's way of representing a dummy, atomic value. Note there is no closing single quote, only a prefixed one. Scheme calls these dummy 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 itself has no parts.) If you think this is all somewhat confusing, you're right. It gets easier with practice.
60
61 `'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 this, just read `(quote the)` as a verbose (and perhaps misleading) way of writing 'the, not as the application of any function to any value.
62
63 Okay, so what we've done is just create a bunch of new atomic values `'the`, `'man`, and so on. Scheme doesn't know how to do much with these. It knows for instance that `'the` is the same value as `'the` and a different value than `'man`. But it doesn't know much more than that. That's all we need or want here.
64
65 And we built a tree out of those values, representing the tree by a nested structure of pairs of leaf-labels.
66
67 The program we submitted to Scheme:
68
69         (cons (cons 'the 'man) 
70                   (cons 'read
71                                 (cons 'the
72                                           'book)))
73
74 evaluates to the nested structure of pairs that Scheme displays as:
75
76         ((the . man) . (read . (the . book)))
77
78 and that we can think of as the tree:
79 ;
80
81              /----------------\
82             /                  \
83            /                    \
84           /                      \
85          /                        \                                  
86         / \                      / \
87        /   \                    /   \
88       /     \                  /     \
89      /       \                /       \
90 meaning of   meaning of   meaning of   \
91   "the"        "man"       "read"      / \
92                                       /   \
93                                      /     \
94                                     /       \
95                                                                 meaning of  meaning of
96                                                                   "the"      "book"
97
98 Okay, let's get back to "damn."
99
100 We start by defining `damn` as a "thunk" that when applied to 0 arguments returns a trivial adjectival meaning, which we'll designate with the dummy symbol `'id`.
101
102 What's a "thunk"?
103
104 Remember, in Scheme you can have functions that take 1 value, and also functions that take 2 values, and also functions that take 0 values. The last ones are called "thunks." The thunk is not identical to the value it returns. For instance:
105
106         (lambda () 3)
107
108 is a thunk that returns the integer 3. If we bind the variable `t` to that thunk, then `t` is a function (Scheme will call it a "procedure") not an integer. Whereas `(t)` is an integer not a function.
109
110 There's no reason yet on hand for us to make `damn` be a thunk. For present purposes, we could also just define `damn` to be the symbol `'id`. But what we're going to go on to do does require us to make `damn` be a thunk. The reason for that is to postpone the evaluation of some expressions until the continuations we want to operate on are in place.
111
112 So for uniformity we're going to make `damn` be a thunk right from the beginning.
113
114 As we said, `damn` starts as a thunk that returns a trivial adjectival meaning `'id`:
115
116         (define damn (lambda () 'id))
117
118 Now we can say:
119
120         (cons (cons 'the 'man) 
121                   (cons 'read
122                                 (cons 'the
123                                           (cons (damn) 
124                                                 'book))))
125
126 and we get back:
127
128         ((the . man) . (read . (the . (id . book))))
129
130
131 Now we want to get some expressive meaning into damn. So we might try:
132
133
134         (define damn (lambda () 'bad))
135
136 But then:
137
138         (cons (cons 'the 'man) 
139                   (cons 'read
140                                 (cons 'the
141                                           (cons (damn) 
142                                                 'book))))
143
144 gives us:
145
146         ((the . man) . (read . (the . (bad . book))))
147
148 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 "bad" to be contributed as a linguistic move on the side. We might try:
149
150         (define damn (lambda () (cons 'side-effect 'bad)))
151
152 But then we'd get:
153
154
155         ((the . man) . (read . (the . ((side-effect . bad) . book))))
156
157 And the context `(the . ( ... . book))` presumably doesn't know how to interact with side-effects. That's precisely the problem we're trying to solve.
158
159
160 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.
161
162 Chris and others have applied the apparatus of continuations to the analysis of expressives in the papers linked above. For a simple in-class demonstration, we tried to do this.
163
164 `(call/cc (lambda k ...))` is Scheme's way of writing: bind the continuation of this very complex expression to k and evaluate the `...`.
165
166 So now we define `damn` like this:
167
168
169         (define damn (lambda () (call/cc (lambda (k) (print "bad") (k 'id)))))
170
171 Now when we do:
172
173         (cons (cons 'the 'man) 
174                   (cons 'read
175                                 (cons 'the
176                                           (cons (damn) 
177                                                 'book))))
178
179 we get something like this:
180
181         <bold>"bad"</bad> ((the . man) . (read . (the . (id . book))))
182
183 Yay! The expressive 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`.
184
185 **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:
186
187         (define three-thunk (lambda () (print "hi") 3))
188
189 and then ask for the evaluation of:
190
191         (+ 2 (three-thunk))
192
193 you'll see something like:
194
195         <bold>"hi"</bad> 5
196
197 So the demonstration we tried in class was pedagogically flawed. It didn't properly display how continuations represent a minimally effective apparatus for representing expressive content. 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.
198
199 So a better demonstration would do without any device like `print` that already incorporates continuations implicitly. Any continuation-manipulation should be fully explicit.
200
201
202
203
204
205
206
207
208 ----- End forwarded message -----
209
210
211
212 #lang racket
213 ;(define damn (lambda () 'id))
214 (define damn (lambda () (call/cc (lambda (k) 
215                                   ; (k 'id)
216                                    (print "Something's bad")
217                                    (k 'id)
218                                    ))))
219
220 (list (list 'the (list (damn) 'man))
221       (list 'read 
222             (list 'the (list (damn) 'book))))
223
224
225
226
227
228 #lang racket
229 (require racket/control)
230
231 (define damn0 (lambda ()
232                                 'id))
233
234 (define damn1 (lambda ()
235                                 (cons '("side effect" bad)
236                                           'id)))
237
238 (define damn2 (lambda () (shift k
239                                                                 (cons '("side effect" bad) 
240                                                                           (list (k 'id))))))
241
242 (define damn3 (lambda () (shift k
243                                                                 (list (k 'id)
244                                                                           '("side effect" bad)))))
245
246
247 ; Now if we use damn0, our compositional semantics will work OK but
248 ; we don't yet have any expressive contribution:
249
250 (list "main content" 'i (list 'like (list 'the (damn0) 'boy)))
251 ; '("main content" i (like (the id boy)))
252
253
254 ; If we use damn1, we've added in the expressive side-effect:
255
256 (list "main content" 'i (list 'like (list 'the (damn1) 'boy)))
257 ; '("main content" i (like (the (("side effect" bad) . id) boy)))
258
259 ; However, the context (list 'the ... 'boy) is now being asked to operate
260 ; on an element (("side effect" bad) . id), and it may complain it doesn't
261 ; know what that is. It knows how to use 'id to get (list 'the 'id 'boy),
262 ; and how to use 'bad to get (list 'the 'bad 'boy), but we're supposed to
263 ; have something different here.
264
265 ; To get what we want we need to use (delimited) continuations:
266 (reset (list "main content" 'i (list 'like (list 'the (damn2) 'boy))))
267 ; '(("side effect" bad) ("main content" i (like (the id boy))))
268
269 ; or to get the side effect at the end:
270
271 (reset (list "main content" 'i (list 'like (list 'the (damn3) 'boy))))
272 ; '(("main content" i (like (the id boy))) ("side effect" bad))
273
274 ; If you're working in the interactive interpreter, the outermost "reset" here
275 ; is already in its default position, so it doesn't need to be explicitly
276 ; specified:
277
278 (list "main content" 'i (list 'like (list 'the (damn2) 'boy)))
279 ; '(("side effect" bad) ("main content" i (like (the id boy))))
280
281 ; However, if you're executing this as a file, you would need to include explicit resets.
282
283
284
285 ; Instead of using reset/shift you could use an element like "print" in
286 ; building the side-effect, as we did in class. Here you wouldn't require an
287 ; explicit continuation, but as Chris said, that's because "print" already
288 ; represents an implicit continuation.
289
290 (define damn4 (lambda () (begin (print "bad") 'id)))
291 (list "main content" 'i (list 'like (list 'the (damn4) 'boy)))
292 ; "bad"'("main content" i (like (the id boy)))
293 ;
294
295
296
297
298 #lang racket
299
300 ; thanks to Ken!
301
302 (let ((pragma
303        ; An ordered pair whose first component is the assertion
304        ; operator, a unary function, and whose second component
305        ; is the meaning of "damn", a thunk.
306        (call-with-current-continuation
307         (lambda (k)
308           (cons (lambda (prop) prop)
309                 (lambda () (k (cons (lambda (prop) (list 'bad prop))
310                                     (lambda () 'id)))))))))
311   (let ((assert (car pragma))
312         (damn   (cdr pragma)))
313     (assert (list 'the 'student 'read 'the (damn) 'book))))
314
315