notes on lambda calculus
[lambda.git] / topics / _week2_lambda_calculus_intro.mdwn
1 Basics of Lambda Calculus
2 =========================
3
4 We often talk about "*the* Lambda Calculus", as if there were just
5 one; but in fact, there are many, many variations.  The one we will
6 start with, and that we will explore in some detail, is the "pure"
7 Lambda Calculus.  And actually, there are many variations even in the
8 pure Lambda Calculus.  But all of the variations share a strong family
9 resemblance, so what we learn now will apply to all of them.
10
11 The lambda calculus we'll be focusing on for the first part of the
12 course has no types. Some prefer to say it does have types, it's just
13 that there's only one type, so that every expression is a member of
14 that one type.  If you say that, you have to say that functions from
15 this type to this type also belong to this type. Which is weird... In
16 fact, though, such types are studied, under the name "recursive
17 types." More about these later in the seminar.
18
19 Here is its syntax:
20
21 <blockquote>
22 <strong>Variables</strong>: <code>x</code>, <code>y</code>, <code>z</code>...
23 </blockquote>
24
25 Each variable is an expression. For any expressions M and N and variable a, the following are also expressions:
26
27 <blockquote>
28 <strong>Abstract</strong>: <code>(&lambda;a M)</code>
29 </blockquote>
30
31 We'll tend to write <code>(&lambda;a M)</code> as just `(\a M)`, so we
32 don't have to write out the markup code for the
33 <code>&lambda;</code>. You can yourself write <code>(&lambda;a
34 M)</code> or `(\a M)` or `(lambda a M)`.
35
36 <blockquote>
37 <strong>Application</strong>: <code>(M N)</code>
38 </blockquote>
39
40 Expressions in the lambda calculus are called "terms".  Here is the
41 syntax of the lambda calculus given in the form of a context-free
42 grammar:
43
44     T --> ( T T )
45     T --> ( lambda Var T)
46     T --> x
47     T --> y
48     ...
49
50 Very, very simple.
51
52 Examples of terms:
53
54         x
55         (y x)
56         (x x)
57         (\x y)
58         (\x x)
59         (\x (\y x))
60         (x (\x x))
61         ((\x (x x)) (\x (x x)))
62
63 The lambda calculus has an associated proof theory. For now, we can regard the
64 proof theory as having just one rule, called the rule of **beta-reduction** or
65 "beta-contraction". Suppose you have some expression of the form:
66
67         ((\a M) N)
68
69 This is an application whose first element is an abstract.  This
70 compound form is called a **redex**, meaning it's a "beta-reducible
71 expression." `(\a M)` is called the **head** of the redex; `N` is
72 called the **argument**, and `M` is called the **body**.
73
74 The rule of beta-reduction permits a transition from that expression to the following:
75
76         M [a <-- N]
77
78 What this means is just `M`, with any *free occurrences* inside `M` of
79 the variable `a` replaced with the term `N`.
80
81 What is a free occurrence?
82
83 >       An occurrence of a variable `a` is **bound** in T if T has the form `(\a N)`.
84
85 >       If T has the form `(M N)`, any occurrences of `a` that are bound in `M` are also bound in T, and so too any occurrences of `a` that are bound in `N`.
86
87 >       An occurrence of a variable is **free** if it's not bound.
88
89 For instance:
90
91 >       T is defined to be `(x (\x (\y (x (y z)))))`
92
93 The first occurrence of `x` in T is free.  The `\x` we won't regard as
94 containing an occurrence of `x`. The next occurrence of `x` occurs
95 within a form that begins with `\x`, so it is bound as well. The
96 occurrence of `y` is bound; and the occurrence of `z` is free.
97
98 Note that the definition of *bound* is carefully crafted to guarantee
99 that in an expression like `(\a (x a))`, both occurrences of `a` count
100 as bound.
101
102 To read further:
103
104 *       [[!wikipedia Free variables and bound variables]]
105
106 Here's an example of beta-reduction:
107
108         ((\x (y x)) z)
109
110 beta-reduces to:
111
112         (y z)
113
114 We'll write that like this:
115
116         ((\x (y x)) z) ~~> (y z)
117
118 Different authors use different notations. Some authors use the term
119 "contraction" for a single reduction step, and reserve the term
120 "reduction" for the reflexive transitive closure of that, that is, for
121 zero or more reduction steps. Informally, it seems easiest to us to
122 say "reduction" for one or more reduction steps. So when we write:
123
124         M ~~> N
125
126 We'll mean that you can get from M to N by one or more reduction
127 steps. 
128
129 There are many more details about the notation and the metatheory of
130 the lambda calculus here:
131
132 *      [[topics/_week2_lambda_calculus_fine_points.mdwn]]
133
134
135 Shorthand
136 ---------
137
138 The grammar we gave for the lambda calculus leads to some
139 verbosity. There are several informal conventions in widespread use,
140 which enable the language to be written more compactly. (If you like,
141 you could instead articulate a formal grammar which incorporates these
142 additional conventions. Instead of showing it to you, we'll leave it
143 as an exercise for those so inclined.)
144
145
146 **Parentheses** Outermost parentheses around applications can be dropped. Moreover, applications will associate to the left, so `M N P` will be understood as `((M N) P)`. Finally, you can drop parentheses around abstracts, but not when they're part of an application. So you can abbreviate:
147
148         (\x (x y))
149
150 as:
151
152         \x (x y)
153
154 but you should include the parentheses in:
155
156         (\x (x y)) z
157
158 and:
159
160         z (\x (x y))
161
162
163 **Dot notation** Dot means "put a left paren here, and put the right
164 paren as far the right as possible without creating unbalanced
165 parentheses". So:
166
167         \x (\y (x y))
168
169 can be abbreviated as:
170
171         \x (\y. x y)
172
173 and that as:
174
175         \x. \y. x y
176
177 This:
178
179         \x. \y. (x y) x
180
181 abbreviates:
182
183         \x (\y ((x y) x))
184
185 This on the other hand:
186
187         (\x. \y. (x y)) x
188
189 abbreviates:
190
191         ((\x (\y (x y))) x)
192
193
194 **Merging lambdas** An expression of the form `(\x (\y M))`, or equivalently, `(\x. \y. M)`, can be abbreviated as:
195
196         (\x y. M)
197
198 Similarly, `(\x (\y (\z M)))` can be abbreviated as:
199
200         (\x y z. M)
201
202
203 Lambda terms represent functions
204 --------------------------------
205
206 Let's pause and consider the following fundamental question: what is a
207 function?  One popular answer is that a function can be represented by
208 a set of ordered pairs.  This set is called the **graph** of the
209 funtion.  If the ordered pair `(a,b)` is a member of the graph if `f`,
210 that means that `f` maps the argument `a` to the value `b`.  In
211 symbols, `f a == b`.  
212
213 There is a requirement that in order to count as a function (rather
214 than as merely a more general relation), the graph cannot contain two
215 (distinct) ordered pairs with the same first element.  That is, in
216 order to count as a proper function, each argument must correspond to
217 a unique result.
218
219 The essential usefullness of the lambda calculus is that it is
220 wonderfully suited to representing functions.  In fact, the untyped
221 lambda calculus is Turing Complete [[!wikipedia Turing Completeness]]:
222 all (recursively computable) functions can be represented by lambda
223 terms.  (As we'll see, much of the fun will be in unpacking the word
224 "represented".)
225
226 For some lambda terms, it is easy to see what function they represent:
227
228 >       `(\x x)` represents the identity function: given any argument `M`, this function
229 simply returns `M`: `((\x x) M) ~~> M`.
230
231 >       `(\x (x x))` duplicates its argument:
232 `((\x (x x)) M) ~~> (M M)`
233
234 >       `(\x (\y (y x)))` reorders its two arguments:
235 `(((\x  (\y (y x))) M) N) ~~> (N M)`
236
237 >       `(\x (\y x))` throws away its second argument:
238 `(((\x (\y x)) M) N) ~~> M`
239
240 and so on.  In order to get an intuitive feel for the power of the
241 lambda calculus, note that duplicating, reordering, and deleting
242 elements is all that it takes to simulate the behavior of a general
243 word processing program.  That means that if we had a big enough
244 lambda term, it could take a representation of *Emma* as input and
245 produce *Hamlet* as a result. 
246
247 Some of these functions are so useful that we'll give them special
248 names.  In particular, we'll call the identity function `(\x.x)`
249 **I**, and the function `(\x\y.x)` **K**.
250
251 It is easy to see that distinct lambda expressions can represent the same
252 function, considered as a mapping from input to outputs. Obviously:
253
254         (\x x)
255
256 and:
257
258         (\z z)
259
260 both represent the same function, the identity function. However, we said above that we would be regarding these expressions as synactically equivalent, so they aren't yet really examples of *distinct* lambda expressions representing a single function. However, all three of these are distinct lambda expressions:
261
262         (\y x. y x) (\z z)
263
264         (\x. (\z z) x)
265
266         (\z z)
267
268 yet when applied to any argument M, all of these will always return M. So they have the same extension. It's also true, though you may not yet be in a position to see, that no other function can differentiate between them when they're supplied as an argument to it. However, these expressions are all syntactically distinct.
269
270 The first two expressions are *convertible*: in particular the first
271 reduces to the second via a single instance of beta reduction. So they
272 can be regarded as proof-theoretically equivalent even though they're
273 not syntactically identical. However, the proof theory we've given so
274 far doesn't permit you to reduce the second expression to the
275 third. So these lambda expressions are non-equivalent.
276
277 To use a linguistic analogy, you can think of what we're calling
278 "proof theory" as a kind of syntactic transformation.  That is, the
279 sentences *John saw Mary* and *Mary was seen by John* are not
280 syntactically identical, yet (on some theories) one can be derived
281 from the other.  The key element in the analogy is that this kind of
282 syntactic derivation is supposed to preserve meaning, so that the two
283 sentence mean (roughly) the same thing.
284
285 There's an extension of the proof-theory we've presented so far which
286 does permit this further move. And in that extended proof theory, all
287 computable functions with the same extension do turn out to be
288 equivalent (convertible). However, at that point, we still wouldn't be
289 working with the traditional mathematical notion of a function as a
290 set of ordered pairs. One reason is that the fully general
291 mathematical notion permits many uncomputable functions, but the
292 lambda calculus is capable of expressing only computable functions. A
293 second reason is that the full mathematical notion prohibits
294 functions from applying to themselves, but in the lambda calculus,
295 it is permitted for a function to take itself as an argument (for
296 instance, there is nothing wrong with applying the identity function
297 to itself, thus: `(\x x)(\x x)`.  This is a redex that reduces to the
298 identity function (of course).
299
300
301 The analogy with `let`
302 ----------------------
303
304 In our basic functional programming language, we used `let`
305 expressions to assign values to variables.  For instance, 
306
307     let x match 2
308     in (x, x) 
309
310 evaluates to the ordered pair (2, 2).  It may be helpful to think of
311 a redex in the lambda calculus as a particular sort of `let`
312 construction.
313
314     ((\x M) N) is analogous to
315
316     let x match N 
317     in M
318
319 This analogy should be treated with caution.  For one thing, our
320 `letrec` allowed us to define recursive functions in which the name of
321 the function appeared within the expression `N`; we're not ready to
322 deal with recursive functions in the lambda calculus yet.  For
323 another, we defined `let` in terms of values, and at this point, the
324 lambda calculus doesn't have values, it only has other expressions.
325 So it might be better to translate `((\x M) N)` as `let x be replaced
326 by N in M`, or some such.  Most problematically, in the lambda
327 calculus, an abstract such as `(\x (x x))` is perfectly well-formed
328 and coherent, but it is not possible to write a `let` expression that
329 does not have an argument (here, `N`) explicitly present.
330
331 Nevertheless, the correspondence is close enough that it can spur
332 intuition.
333
334
335 Booleans and pairs
336 ==================
337
338 So if the lambda calculus can represent any computable function, we
339 need to do some work to show how to represent some of the functions
340 we've become acquainted with.  We'll start with the `if ... then
341 ... else...` construction.
342
343     if x then y else z
344
345 For a boolean expression `x`, this complex expression evaluates to `y`
346 if `x` evaluates to `'true`, and to `z` if `x` evaluations to `'false.
347 So in order to simulate and `if` clause in the lambda calculus, we
348 need to settle on a way to represent `'true` and `'false`.
349
350 We could simply add the constants `'true` and `'false` to the
351 language, since it makes sense to add constants to the lambda
352 calculus.  However, that would also require complicating the
353 interpretation of the language; at the very least, we would need more
354 than just beta reduction as our engine of computation.  In the spirit
355 of computational minimalism, let's see how far we can get with the
356 pure lambda calculus, without any special constants.
357
358 So we'll need to get rid of the parts of the `if` statement that are
359 just syntactic window-dressing.  That is, we'll need to get rid of the
360 `if`, the `then`, and the `else`:
361
362     M  N  L
363
364 Recall that our convention is that values associate left to right, so
365 this series of terms is evaluated as
366
367     ((M N) L)
368
369 If this expression is supposed to have the meaning of `if M then N
370 else L`, then we need to find a value for `'true` such that when it is
371 substituted in place of `M`, the expression evaluates to `N`.  The
372 function we're looking for takes two arguments: first `N`, then `L`,
373 throws away `L`, and returns `N`.  
374
375 We've already seen such a function.  We called it **K**: `(\x\y.x)`.
376 Let's test:
377
378     ((K M) L) == (((\x\y.x) M) L) ~~> ((\y.M) L) ~~> M
379
380 Sucess!  In the same spirit, `'false` will be **KI**:
381
382     (((K I) M) L) == ((((\x\y.x)(\x.x)) M) L) 
383                      ~~> (((\y.(\x.x)) M) L)
384                      ~~> ((\x.x) L)
385                      ~~> L
386
387 So have seen our first major representation in the lambda calculus:
388 "true" is represented by **K**, and "false" is represented by **KI**.
389 We'll be building up a lot of representations in the weeks to come,
390 and they will all maintain the discipline that if a expression is
391 meant to be interpreted as a truth value (i.e., as a Boolean), it will
392 evaluate to (an expression that is alpha-beta-eta equivalent to) **K**
393 or **KI**.
394
395 Our definition of these is reviewed in [[Assignment 2|topics/assignment2]].
396
397 It's possible to do the assignment without using a Scheme interpreter, however
398 you should take this opportunity to [get Scheme installed on your
399 computer](/how_to_get_the_programming_languages_running_on_your_computer), and
400 [get started learning Scheme](/learning_scheme). It will help you test out
401 proposed answers to the assignment.
402
403
404 There's also a (slow, bare-bones, but perfectly adequate) version of Scheme available for online use at <http://tryscheme.sourceforge.net/>.
405