This is a friendly Lambda Calculus Introduction by Dustin Mulcahey. LISP has its syntactic roots in a formal system called the lambda calculus. After a brief discussion of formal systems and logic in general, Dustin will dive in to the lambda calculus and make enough constructions to convince you that it really is capable of expressing anything that is "computable". Dustin then talks about the simply typed lambda calculus and the Curry-Howard-Lambek correspondence, which asserts that programs and mathematical proofs are "the same thing".
6. For computer scientists, the most interesting part of
this discussion is Hilbert’s Entscheidungsproblem.
7. For computer scientists, the most interesting part of
this discussion is Hilbert’s Entscheidungsproblem.
8. For computer scientists, the most interesting part of
this discussion is Hilbert’s Entscheidungsproblem.
Entscheidungsproblem: Given a mathematical
statement, is there an algorithm that will compute a
proof or a refutation of that statement?
9. For computer scientists, the most interesting part of
this discussion is Hilbert’s Entscheidungsproblem.
Entscheidungsproblem: Given a mathematical
statement, is there an algorithm that will compute a
proof or a refutation of that statement?
At the time of its statement by Hilbert, there was
no formalization of “algorithm”.
11. Fast-forward to the late 1920s...
Schoenfinkel: “Bound variables are bad. (or, at
least, unnecessary)”
12. Schoenfinkel defined the basic combinators that
form the “combinatory logic” (SKI). We’ll define
these in terms of the lambda calculus, once we’ve
defined that.
13. Schoenfinkel defined the basic combinators that
form the “combinatory logic” (SKI). We’ll define
these in terms of the lambda calculus, once we’ve
defined that.
Haskell Curry also formulated the concept of
“combinator” in his efforts to unambiguously define
substitution, which had been rather loosely
described up until his time (and continues to be
loosely described up to this day).
14. Schoenfinkel also seems to have originated the
notion of “currying” (named after Haskell Curry).
This is the idea that you can take a two argument
function
F (x, y )
and express it as a one argument function that is
valued in functions:
(f (x))(y )
15. Finally, on to Alonzo Church!
Goal: a new formal system for logic based upon the
notion of function application. He wanted
something “more natural” than Russell-Whitehead
or ZF.
16. The formal system that he developed is called the
lambda calculus.
Here is the identity function expressed in the
lambda calculus:
17. The formal system that he developed is called the
lambda calculus.
Here is the identity function expressed in the
lambda calculus:
λx.x
19. Why use λ for function abstraction?
Whitehead and Russell used x for class abstraction.
ˆ
If you move the hat off the x, you get ∧x.
Apparently, λx was easier to print than ∧x.
20. Why use λ for function abstraction?
Whitehead and Russell used x for class abstraction.
ˆ
If you move the hat off the x, you get ∧x.
Apparently, λx was easier to print than ∧x.
At least, that’s how Church told it at one point.
Later in life, he claimed that he needed a symbol
and he just happened to choose λ.
21. In a formal system, we must give clear rules about
what sequence of symbols can be produced and how
they can be transformed. It’s very similar to
designing a programming language.
22. To formulate the lambda calculus, we must first fix
a set of letters that we will use for variables.
Typically, we denote these by x, y (we rarely need
more than two). Once this has been done, we
inductively define valid lambda terms:
If x is a variable, then x is a valid lambda term.
If t is a valid lambda term and x is a variable,
then (λx.t) is a valid lambda term. (Lambda
Abstraction)
If t, s are valid lambda terms, then (t s) is a
valid lambda term. (Application)
23. That’s it! We can now construct all sorts of lambda
terms:
x
(λx.x)
y
(y y )
((λx.x)(y y ))
(λy .((λx.x)(y y )))
(variable)
(lambda abstraction)
(variable)
(application)
(application)
(lambda abstraction)
24. While I have given the intuition behind the above
constructs, they are mere scribblings on paper until
we give rules for manipulating the terms. From a
proof-theoretic perspective, meaning arises from the
reduction rules of the language.
25. While I have given the intuition behind the above
constructs, they are mere scribblings on paper until
we give rules for manipulating the terms. From a
proof-theoretic perspective, meaning arises from the
reduction rules of the language.
This is quite different from other notions of
meaning, such as Tarski’s definition of truth or
denotionation semantics (in fact, we shall see that
denotational semantics turns out to be an
interesting problem for the lambda calculus).
26. There are three rules for manipulating lambda
terms:
α-equivalence: renaming variables
β-reduction: how function application “works”
η-conversion: two functions are “the same” if
they do the same thing (extensionality)
28. α-equivalence lets us convert λx.x to λy .y . Makes
sense, right? They are both the identity function.
Generally, α-equivalence lets us rename any bound
variables.
29. As programmers, we use α-equivalence to reason
about lexical scoping:
x = 0
f = function(x, y) {
return x + y;
}
print f(3,4);
31. As you can imagine, formally defining α-equivalence
is a bit tricky. We want λx.x α-equivalent to λy .y ,
but we do not want λx.(λy .x) α-equivalent to
λy .(λy .y ).
32. As you can imagine, formally defining α-equivalence
is a bit tricky. We want λx.x α-equivalent to λy .y ,
but we do not want λx.(λy .x) α-equivalent to
λy .(λy .y ).
(The first takes a value and produces the constant
function at that value, while the second returns the
identity function no matter what’s passed to it.)
33. β-reduction captures the notion of function
application. However, to formally define it, we run
in to the substitution problem again!
34. β-reduction captures the notion of function
application. However, to formally define it, we run
in to the substitution problem again!
Intuitively, we would like (f x) to denote the
application of a function f to an input x. Of course,
in this world, everything has the same “type”, so we
are really applying one lambda term to another.
35. For a simple example of β-reduction, let’s apply the
identity function to something.
((λx.x)(λy .(y y ))
36. For a simple example of β-reduction, let’s apply the
identity function to something.
((λx.x)(λy .(y y ))
ought to reduce to
(λy .(y y ))
38. How about the other way around?
((λy .(y y ))(λx.x)
((λx.x)(λx.x))
39. How about the other way around?
((λy .(y y ))(λx.x)
((λx.x)(λx.x))
(λx.x)
40. We define β-reduction as follows. Let
((λx.t) s)
be a valid lambda term with t and s lambda terms
and x a variable. The above reduces to
t[s/x]
where t[s/x] denotes the result of replacing every
occurrence of x in t by s.
41. Problem: what if our usage of variables is a bit too
incestuous?
42. Problem: what if our usage of variables is a bit too
incestuous?
Example:
t = (λz.(x y ))
s =z
43. Problem: what if our usage of variables is a bit too
incestuous?
Example:
t = (λz.(x y ))
s =z
Now apply β-reduction:
((λx.t) s)
((λx.(λz.(x y ))) z)
(λz.(z y ))
44. Whereas if we first did α-equivalence:
t = (λw .(x y ))
s =z
45. Whereas if we first did α-equivalence:
t = (λw .(x y ))
s =z
46. Whereas if we first did α-equivalence:
t = (λw .(x y ))
s =z
And then apply β-reduction:
((λx.t) s)
((λx.(λw .(x y ))) z)
(λw .(z y ))
The function on the previous slide applies its
parameter to the free variable y , whereas the
function on this slide does nothing with its
parameter!
47. So, obviously some care is needed when defining
substitution.
We need to ensure that in
((λx.t) s)
that s does not contain a free variable that becomes
bound when s is substituted for x in t.
48. The next and final reduction expresses the
mathematical principle of extensionality.
49. The next and final reduction expresses the
mathematical principle of extensionality.
Informally, we say that two functions are
extensionally equal if they do the same thing.
50. The next and final reduction expresses the
mathematical principle of extensionality.
Informally, we say that two functions are
extensionally equal if they do the same thing.
That is,
f (x)
=x +2
g (x) = x + 1 + 1
are two different functions as I have written them,
but extensionally equal.
51. However (as an aside),
2
−4
f (x) = xx−2
g (x) = x + 2
Are neither equal nor extensionally equal, but
algebraically reduce to the same thing.
52. η-conversion captures this notion by stating that, for
lambda expressions f not containing the variable x,
(λx.(f x))
is equivalent to
f
54. Well, I can do what any beginning (or intermediate,
or advanced) programmer does:
((λx.(x x))(λx.(x x)))
55. Well, I can do what any beginning (or intermediate,
or advanced) programmer does:
((λx.(x x))(λx.(x x)))
Let’s apply β-reduction:
56. Well, I can do what any beginning (or intermediate,
or advanced) programmer does:
((λx.(x x))(λx.(x x)))
Let’s apply β-reduction:
((λx.(x x))(λx.(x x)))
Yay! An infinite loop!
So we see that the true strength of the lambda
calculus is the speed at which we can write down
infinite computations.
61. Or, even better:
(λx.((x x) x)(λx.((x x) x)
(((λx.((x x) x) (λx.((x x) x)) (λx.((x x) x))
((((λx.((x x) x) (λx.((x x) x)) (λx.((x x) x)) (λx.((x x
.
.
.
This example shows that not all lambda terms
normalize. That is, given a lambda term, you can’t
always just whack it with β-reduction until it settles
into something!
62. To make things that are more interesting than
non-terminating programs, we need to define some
basic things. I will now define the following:
numbers
63. To make things that are more interesting than
non-terminating programs, we need to define some
basic things. I will now define the following:
numbers
booleans and conditionals
64. To make things that are more interesting than
non-terminating programs, we need to define some
basic things. I will now define the following:
numbers
booleans and conditionals
recursion
66. The standard formulation of the natural numbers is
called the system of Church Numerals.
Intuition: The number n is n-fold composition.
67. The standard formulation of the natural numbers is
called the system of Church Numerals.
Intuition: The number n is n-fold composition.
(Speaking of non-termination...)
68. Less cyclic: The number n is a function that takes a
function and returns the nth-fold composite of that
function.
69. Less cyclic: The number n is a function that takes a
function and returns the nth-fold composite of that
function.
(Hmm, still looks cyclic to me.)
70. Less cyclic: The number n is a function that takes a
function and returns the nth-fold composite of that
function.
(Hmm, still looks cyclic to me.)
That is,
n(f ) = f ◦ f ◦ f ◦ . . . ◦ f
71. Less cyclic: The number n is a function that takes a
function and returns the nth-fold composite of that
function.
(Hmm, still looks cyclic to me.)
That is,
n(f ) = f ◦ f ◦ f ◦ . . . ◦ f
which we can denote as f ◦n .
90. You’ll notice that I’ve suddenly started using the
symbol ≡
If a ≡ b, I’m declaring by the powers of notation
that wherever you write a, you can also write b (and
vice versa).
91. Also note that succ is itself a lambda term:
succ ≡ λn.λf .λx.(f ((n f ) x))
Here, n is not boldface because I’m using it as a
variable. The user of our succ function could put
anything there! Of course, we only gaurantee good
behavior on an input that is equivalent to a natural
number (as we have defined them).
93. Okay, we have natural numbers. How about
addition?
Intuition: n + m takes a function and composes it
n + m times.
94. Okay, we have natural numbers. How about
addition?
Intuition: n + m takes a function and composes it
n + m times. Strategy: Let’s write a lambda term
that applies f m times, “and then”applies it n
times.
95. Okay, we have natural numbers. How about
addition?
Intuition: n + m takes a function and composes it
n + m times. Strategy: Let’s write a lambda term
that applies f m times, “and then”applies it n
times. In the world of functions, “and then” means
composition! So addition corresponds to
composition.
96. Okay, we have natural numbers. How about
addition?
Intuition: n + m takes a function and composes it
n + m times. Strategy: Let’s write a lambda term
that applies f m times, “and then”applies it n
times. In the world of functions, “and then” means
composition! So addition corresponds to
composition.
add ≡ (λn.λm.λf .λx.((n f ) ((m f ) x)))
97. Theorem: ((add 2) 2) is equivalent to 4
Proof: (I’m going to use a mixture of definitional
equality and reductions)
((add 2) 2)
98. Theorem: ((add 2) 2) is equivalent to 4
Proof: (I’m going to use a mixture of definitional
equality and reductions)
((add 2) 2)
(((λn.λm.λf .λx.((n f ) ((m f ) x))) 2) 2)
99. Theorem: ((add 2) 2) is equivalent to 4
Proof: (I’m going to use a mixture of definitional
equality and reductions)
((add 2) 2)
(((λn.λm.λf .λx.((n f ) ((m f ) x))) 2) 2)
((λm.λf .λx.((2 f ) ((m f ) x))) 2)
100. Theorem: ((add 2) 2) is equivalent to 4
Proof: (I’m going to use a mixture of definitional
equality and reductions)
((add 2) 2)
(((λn.λm.λf .λx.((n f ) ((m f ) x))) 2) 2)
((λm.λf .λx.((2 f ) ((m f ) x))) 2)
(λf .λx.((2 f ) ((2 f ) x)))
(λf .λx.(((λf .λx.(f (f x)) f ) ((λf .(λx.(f (f x)) f ) x)))
101. Theorem: ((add 2) 2) is equivalent to 4
Proof: (I’m going to use a mixture of definitional
equality and reductions)
((add 2) 2)
(((λn.λm.λf .λx.((n f ) ((m f ) x))) 2) 2)
((λm.λf .λx.((2 f ) ((m f ) x))) 2)
(λf .λx.((2 f ) ((2 f ) x)))
(λf .λx.(((λf .λx.(f (f x)) f ) ((λf .(λx.(f (f x)) f ) x)))
(λf .λx.((λx.(f (f x)) (λx.(f (f x)) x)))
102. Theorem: ((add 2) 2) is equivalent to 4
Proof: (I’m going to use a mixture of definitional
equality and reductions)
((add 2) 2)
(((λn.λm.λf .λx.((n f ) ((m f ) x))) 2) 2)
((λm.λf .λx.((2 f ) ((m f ) x))) 2)
(λf .λx.((2 f ) ((2 f ) x)))
(λf .λx.(((λf .λx.(f (f x)) f ) ((λf .(λx.(f (f x)) f ) x)))
(λf .λx.((λx.(f (f x)) (λx.(f (f x)) x)))
(λf .λx.((λx.(f (f x)) (f (f x))))
103. Theorem: ((add 2) 2) is equivalent to 4
Proof: (I’m going to use a mixture of definitional
equality and reductions)
((add 2) 2)
(((λn.λm.λf .λx.((n f ) ((m f ) x))) 2) 2)
((λm.λf .λx.((2 f ) ((m f ) x))) 2)
(λf .λx.((2 f ) ((2 f ) x)))
(λf .λx.(((λf .λx.(f (f x)) f ) ((λf .(λx.(f (f x)) f ) x)))
(λf .λx.((λx.(f (f x)) (λx.(f (f x)) x)))
(λf .λx.((λx.(f (f x)) (f (f x))))
(λf .λx.(λf .(f (f (f (f x))))))
4
104. As you can see, doing arithmetic with Church
numerals is both simple and fun.
What about multiplication?
105. Intuition: (n ∗ m) takes a function and returns the
n ∗ mth fold composite of the function with itself.
Strategy: Make the mth composite of f n times.
106. Intuition: (n ∗ m) takes a function and returns the
n ∗ mth fold composite of the function with itself.
Strategy: Make the mth composite of f n times.
mult = λn.λm.λf .λx.((n (m f )) x)
108. Theorem: ((mult 2) 2) is equivalent to 4
Proof: This is left as an exercise for the reader.
109. Exponentiation is also straightforward:
Strategy: To get mn , apply n to m. Remember that
m takes a function and returns the mth fold
composite. So now we take the nth fold composite
of the function that takes a function and returns the
mth fold composite. So now we have a function
that takes a function and returns the mn th fold
composite.
110. Exponentiation is also straightforward:
Strategy: To get mn , apply n to m. Remember that
m takes a function and returns the mth fold
composite. So now we take the nth fold composite
of the function that takes a function and returns the
mth fold composite. So now we have a function
that takes a function and returns the mn th fold
composite. Clear, right? How about this:
111. Exponentiation is also straightforward:
Strategy: To get mn , apply n to m. Remember that
m takes a function and returns the mth fold
composite. So now we take the nth fold composite
of the function that takes a function and returns the
mth fold composite. So now we have a function
that takes a function and returns the mn th fold
composite. Clear, right? How about this:
(n m)f = (m ◦ m ◦ · · · ◦ m)f
112. Exponentiation is also straightforward:
Strategy: To get mn , apply n to m. Remember that
m takes a function and returns the mth fold
composite. So now we take the nth fold composite
of the function that takes a function and returns the
mth fold composite. So now we have a function
that takes a function and returns the mn th fold
composite. Clear, right? How about this:
(n m)f = (m ◦ m ◦ · · · ◦ m)f
(Remember that composition corresponds to
addition.)
114. Subtraction is much trickier. The most
understandable way to do it (that I know of) is to
use pairing.
Idea: Instead of incrementing x to x + 1, let’s take
the pair (n, m) to the pair (m, m + 1). If we start at
(0, 0), we’ll get the following sequence:
115. Subtraction is much trickier. The most
understandable way to do it (that I know of) is to
use pairing.
Idea: Instead of incrementing x to x + 1, let’s take
the pair (n, m) to the pair (m, m + 1). If we start at
(0, 0), we’ll get the following sequence:
(0, 0) → (0, 1) → (1, 2) → (2, 3) · · ·
116. Subtraction is much trickier. The most
understandable way to do it (that I know of) is to
use pairing.
Idea: Instead of incrementing x to x + 1, let’s take
the pair (n, m) to the pair (m, m + 1). If we start at
(0, 0), we’ll get the following sequence:
(0, 0) → (0, 1) → (1, 2) → (2, 3) · · ·
So, to get the predecessor of n, we just do the
above process n times and then take the first
coordinate of the result. How’s that for efficiency?
124. To make a pair of lambda terms, we will store them
both in a cond. To get the first, we apply cond to
true. To get the second, we apply cond to false.
125. To make a pair of lambda terms, we will store them
both in a cond. To get the first, we apply cond to
true. To get the second, we apply cond to false.
pair ≡ λf .λs.λc.(((cond c)s)t)
126. To make a pair of lambda terms, we will store them
both in a cond. To get the first, we apply cond to
true. To get the second, we apply cond to false.
pair ≡ λf .λs.λc.(((cond c)s)t)
127. What about my pair increment function?
paircrement ≡ λp.((pair (p false))(succ (p true)))
132. Phew! We now have conditionals and arithmetic.
... and with pairs, we could go ahead and define the
rationals right now. But I’m not going to.
133. Phew! We now have conditionals and arithmetic.
... and with pairs, we could go ahead and define the
rationals right now. But I’m not going to.
Instead, I want to plunge into recursion!
134. Okay, to do recursion, I need a function to call
itself.
135. Okay, to do recursion, I need a function to call
itself. Except in our formal system of lambda
calculus, there is no notion of variable binding. All
we have are ways of constructing lambda terms and
ways of reducing them to other lambda terms.
136. Okay, to do recursion, I need a function to call
itself. Except in our formal system of lambda
calculus, there is no notion of variable binding. All
we have are ways of constructing lambda terms and
ways of reducing them to other lambda terms. How
do we do this?
137. Yes, this is where we start talking about the Y
combinator.
138. Yes, this is where we start talking about the Y
combinator.
There are a bunch of explanations of this thing, and
what follows is one of them.
139. Let’s start with a recursive function:
fact ≡ λn. ((((cond (isZero n)) 1) ((mult n) (fact
(pred n))))
140. Let’s start with a recursive function:
fact ≡ λn. ((((cond (isZero n)) 1) ((mult n) (fact
(pred n))))
This would only make sense if we could make
recursive definitional equalities. But, if you think
about it, if we could, then we would just be writing
forever...
141. Well, we can’t refer to a function by name (except
in the very limited sense of ≡). But what if we
could pass a function to itself?
fact ≡ λf . λn. ((((cond (isZero n)) 1) ((mult n) (f
(pred n))))
Well, it wouldn’t make much sense to reduce (fact
fact), since we would have to reduce (fact (pred n)),
which doesn’t make sense.
142. But what if we had a magic function g such that g
is equivalent to (fact g )?
Then, the following would happen (for example):
143. But what if we had a magic function g such that g
is equivalent to (fact g )?
Then, the following would happen (for example):
((fact g ) 4)
144. But what if we had a magic function g such that g
is equivalent to (fact g )?
Then, the following would happen (for example):
((fact g ) 4)
((λf . λn. ((((cond (isZero n)) 1) ((mult n) (f (pred
n)))) g ) 4)
145. But what if we had a magic function g such that g
is equivalent to (fact g )?
Then, the following would happen (for example):
((fact g ) 4)
((λf . λn. ((((cond (isZero n)) 1) ((mult n) (f (pred
n)))) g ) 4)
λn. ((((cond (isZero n)) 1) ((mult n) (g (pred n))))
4)
146. But what if we had a magic function g such that g
is equivalent to (fact g )?
Then, the following would happen (for example):
((fact g ) 4)
((λf . λn. ((((cond (isZero n)) 1) ((mult n) (f (pred
n)))) g ) 4)
λn. ((((cond (isZero n)) 1) ((mult n) (g (pred n))))
4)
((((cond (isZero 4)) 1) ((mult n) (g (pred 4))))
147. But what if we had a magic function g such that g
is equivalent to (fact g )?
Then, the following would happen (for example):
((fact g ) 4)
((λf . λn. ((((cond (isZero n)) 1) ((mult n) (f (pred
n)))) g ) 4)
λn. ((((cond (isZero n)) 1) ((mult n) (g (pred n))))
4)
((((cond (isZero 4)) 1) ((mult n) (g (pred 4))))
((mult n) (g (pred 4)))
148. But what if we had a magic function g such that g
is equivalent to (fact g )?
Then, the following would happen (for example):
((fact g ) 4)
((λf . λn. ((((cond (isZero n)) 1) ((mult n) (f (pred
n)))) g ) 4)
λn. ((((cond (isZero n)) 1) ((mult n) (g (pred n))))
4)
((((cond (isZero 4)) 1) ((mult n) (g (pred 4))))
((mult n) (g (pred 4)))
((mult n) (g 3))
149. But what if we had a magic function g such that g
is equivalent to (fact g )?
Then, the following would happen (for example):
((fact g ) 4)
((λf . λn. ((((cond (isZero n)) 1) ((mult n) (f (pred
n)))) g ) 4)
λn. ((((cond (isZero n)) 1) ((mult n) (g (pred n))))
4)
((((cond (isZero 4)) 1) ((mult n) (g (pred 4))))
((mult n) (g (pred 4)))
((mult n) (g 3))
((mult n) ((fact g ) 3))
151. Such a magic g is the fixed point of fact.
A fixed point of a function f is a value x such that
f (x) = x
152. Such a magic g is the fixed point of fact.
A fixed point of a function f is a value x such that
f (x) = x
For example: if f (x) = x 2 then 0, 1 are the fixed
points of f .
153. In the lambda calculus, there is a lambda term that
will compute the fixed point of any other lambda
term. This is referred to as the Y -combinator.
Note that there are several flavors of Y combinator.
155. Theorem: for any lambda term h, (Y h) is
equivalent to (h (Y h)).
Proof:
156. Theorem: for any lambda term h, (Y h) is
equivalent to (h (Y h)).
Proof:
(Y h)
157. Theorem: for any lambda term h, (Y h) is
equivalent to (h (Y h)).
Proof:
(Y h)
(λ f. ((λ x. (f (x x))) (λ x. (f (x x)))) h)
158. Theorem: for any lambda term h, (Y h) is
equivalent to (h (Y h)).
Proof:
(Y h)
(λ f. ((λ x. (f (x x))) (λ x. (f (x x)))) h)
((λ x. (h (x x))) (λ x. (h (x x)))
159. Theorem: for any lambda term h, (Y h) is
equivalent to (h (Y h)).
Proof:
(Y h)
(λ f. ((λ x. (f (x x))) (λ x. (f (x x)))) h)
((λ x. (h (x x))) (λ x. (h (x x)))
(h ((λ x. (h (x x)) (λ x. (h (x x))))
160. Theorem: for any lambda term h, (Y h) is
equivalent to (h (Y h)).
Proof:
(Y h)
(λ f. ((λ x. (f (x x))) (λ x. (f (x x)))) h)
((λ x. (h (x x))) (λ x. (h (x x)))
(h ((λ x. (h (x x)) (λ x. (h (x x))))
(h (Y h))
161. So really, factorial is defined in two steps:
fact’ ≡ λf . λn. ((((cond (isZero n)) 1) ((mult n) (f
(pred n))))
fact ≡ (Y fact’)
162. Which is definitionally equivalent to this:
((λf . ((λx. (f (x x))) (λx. (f (x x)))) (λf . λn.
((((λc.λt.λf . ((c t) f (λn. ((n (λx. (λx.λy .y )))
(λx.λy .x)) n)) (λf .λx.(fx))) (((λn.λm.λf . (n (m
(f )))) n) (f ((λn. (((n (λp. (((λf .λs.λc.
((((λc.λt.λf .((c t) f ) c) s) t)) (p (λx.λy .y )))
((λf .λx. (f ((n f ) x)) (p (λx.λy .x))))))
(((λf .λs.λc. ((((λc.λt.λf .((c t) f ) c) s) t))
(λf .λx.x)) (λf .λx.x)) (λx.λy .x))) n))))))
163. Now that we’ve defined the lambda calculus and
written a program in it, I want to discuss some
properties of the system as a whole.
164. The Church-Turing Thesis
Any algorithm that performs a computation can be
expressed in the λ-calculus, or by a Turing machine,
or by a recursive function (in the sense of recursion
theory).
166. The Church-Rosser Theorem
In the λ-calculus, given terms t1 and t2 gotten from
a common term t by a sequence of reductions, there
exists a term s that t1 and t2 both reduce to.
167. The Church-Rosser Theorem
In the λ-calculus, given terms t1 and t2 gotten from
a common term t by a sequence of reductions, there
exists a term s that t1 and t2 both reduce to.
t
/t
/s
t2
1
168. Equivalence of the λ-calculus and combinatory logic.
Define combinators:
I = λx.x
K = λx.λy .x
S = λx.λy .λz.((x z) (y z))
Then these combinators suffice to construct any
lambda term, up to equivalence.
169. Equivalence of the λ-calculus and combinatory logic.
Define combinators:
I = λx.x
K = λx.λy .x
S = λx.λy .λz.((x z) (y z))
Then these combinators suffice to construct any
lambda term, up to equivalence.
For example,
Y = S (K (S I I)) (S (S (K S) K) (K (S I I)))
170. Correspondence between SK and propositional logic
Consider the axiom of propositional logic:
a =⇒ (b =⇒ a)
171. Correspondence between SK and propositional logic
Consider the axiom of propositional logic:
a =⇒ (b =⇒ a)
Now look at the K combinator again:
λa.λb.a
172. Correspondence between SK and propositional logic
Consider the axiom of propositional logic:
a =⇒ (b =⇒ a)
Now look at the K combinator again:
λa.λb.a
Now repeat this to yourself:
“If I have a proof of a, then given a proof of b, I still
have a proof of a”
173. Now consider the axiom:
(a =⇒ (b =⇒ c)) =⇒ ((a =⇒ b) =⇒ (a =⇒ c))
174. Now consider the axiom:
(a =⇒ (b =⇒ c)) =⇒ ((a =⇒ b) =⇒ (a =⇒ c))
Now look at the S combinator again:
λf .λg .λa.((f a)(g a))
175. Now consider the axiom:
(a =⇒ (b =⇒ c)) =⇒ ((a =⇒ b) =⇒ (a =⇒ c))
Now look at the S combinator again:
λf .λg .λa.((f a)(g a))
Now, repeat this to yourself:
“If I have a way f of turning proofs of a into proofs
that b implies c, then given a proof g that a implies
b, I can make a proof that a implies c.”
176. Really, the only sane way to think about this stuff is
to appeal to category theory.
177. Really, the only sane way to think about this stuff is
to appeal to category theory.
The proposition
a =⇒ (b =⇒ a)
178. Really, the only sane way to think about this stuff is
to appeal to category theory.
The proposition
a =⇒ (b =⇒ a)
Corresponds to an object (“function space”). Think
of A as the set of proofs of the proposition a.
(AB )A
179. Really, the only sane way to think about this stuff is
to appeal to category theory.
The proposition
a =⇒ (b =⇒ a)
Corresponds to an object (“function space”). Think
of A as the set of proofs of the proposition a.
(AB )A
Which, in nice categories is isomorphic to
A(A×B)
180. Really, the only sane way to think about this stuff is
to appeal to category theory.
The proposition
a =⇒ (b =⇒ a)
Corresponds to an object (“function space”). Think
of A as the set of proofs of the proposition a.
(AB )A
Which, in nice categories is isomorphic to
A(A×B)
(All I’ve done here is uncurry.)
181. The latter function space contains the first
projection (which looks an awful lot like K). The
existence of this first projection shows that the type
AA×B is inhabited, and thus the original proposition
a =⇒ (b =⇒ a) is valid.
182. The correspondence between lambda expression,
logical formulas, and objects in categories is called
the Curry-Howard-Lambek correspondence.