It seems that people either love things like lambda calculus and eat it up, or their eyes gloss over and they don't care or want to learn about it. I was firmly part of the latter group, until I took a class in college that forced me to learn about it. The thing is, once you learn more about a subject like this, the less you'll understand why you were so averse to learning about it.
In the spirit of broadening our horizons, let's explore the lambda calculus and see if it's as hard as it's cracked up to be. I don't claim to be a wizard at this stuff, and by no means am I a theoretical computer scientist, but that's not the goal. The goal is to cut down on the formality and see if we can expore this stuff a bit. First, let's look at a very basic function: addition. In lambda calculus it looks like this:
λ x. x + 1
That is, a function whose argument is named x, returns the value x + 1. This looks really similar to some syntax that we have in Python. Let's see if we can find a corollary to help make things easier:
lambda x: x + 1
Surprisingly, the syntax is almost the same! It's an anonymous function which takes x as its one argument and returns x + 1. Lambda calculus doesn't have powerful enough syntax for talking about functions with multiple arguments, though, so you may think that it's not very powerful. Thanks to a technique called currying, however, we can express functions with infinite numbers of arguments. This is how that might look:
λ x. λ y. x + y
This is where I think the syntax starts to get in the way of readability. Let's see what this would look like in Python:
lambda x: lambda y: x + y
Hmmm...it's not much more readable, but at least we can open up an interactive interpreter to see what we're doing. Basically what we're doing is creating a function which returns another function. That inner function then has access not only to its single argument, but to its parent's argument as well. Let's demonstrate that this works:
>>> add = lambda x: lambda y: x + y
>>> add(5)(4)
9
Now does this work if we start to change the variable names? What if I just decide that I can't stand the letter x and don't want it inside any more of my functions. Well I can simply change the variable name, as long as I change any uses of that variable. It would work just the same:
>>> add = lambda z: lambda y: z + y
>>> add(5)(4)
9
In this instance, we have changed all of our instances of x with z. This ability to change the names of bound variables is the first rule of lambda calculus, and it's called α-conversion.
As developers, we intuitively understand the idea of function application. We understand that a function which takes in an argument replaces all references to that argument with the given value, and returns a result. For example, in the addition function, lets go through the steps for function application:
>>> add = lambda x: lambda y: x + y
>>> add5 = add(5)
# We can envision what's happening here by replacing x with 5
# add5 = lambda 5: lambda y: 5 + y
# add5 = lambda y: 5 + y
>>> add5(4)
# And now the final function application, resulting in a value
# lambda 4: 5 + 4
9
This idea of function application, in lambda calculus is given the name β-reduction. To review, in lambda calculus syntax that process would look like so:
(λ x. λ y. x + y) 5
(λ y. 5 + y) 4
5 + 4
9
Something that we also intuitively know as developers is that functions can do the exact thing, but have very different implementations. For example this function:
λ x. x + x
...will give the same results for all values as this function:
λ x. x * 2
We understand that code which uses the former function can easily swap out the latter and expect the program the function correctly. This idea is called η-conversion in lambda calculus.
See, this is pretty simple stuff! Obviously there are subtleties that I didn't go into, and it gets a bit more confusing when we start to try to figure out formally which variables occur bound and which occur free, and as we attempt to preserve that status while doing α-conversion, β-reduction, and η-conversion.
Here's some really mind bending food for thought:
(λ x. x x) (λ x. x x)
Think about how this would reduce:
(λ x. x x) (λ x. x x)
(λ (λ x. x x). (λ x. x x) (λ x. x x))
(λ x. x x) (λ x. x x)
As you can see, we could do this forever. This is called the ω combinator, and it lets us do some really cool things with recursion. Maybe more on that in a later blog post.
What is all of this good for? Well, with only this very simple, rigidly defined ruleset, we can express every possible computer program. That makes it very good for doing mathematical proofs and other various scholarly things when we want to explore algorithms. It also forms the basis of all programming languages, and especially functional programming languages.
Of particular interest to me is that we can actually represent numbers, truth, and logic using only these very basic primitives. I'll explore that in another post. To me, all of this is fascinating, and it's hard to believe that before my teacher forced me to learn it, I actively didn't want to know about it.
All Content


By James Tauber at 1:43 a.m. on Nov. 20, 2008
This is actually a nice backgrounder to where I'm planning on going after my first post of the month: Two Fun(ctional) Questions. Although as you might be able to guess, I'm coming at it more from a combinatory logic perspective rather than a lambda calculus perspective.
By James Tauber at 2:50 a.m. on Nov. 20, 2008
Now see: http://jtauber.com/blog/2008/11/20/more_questions_on_the_path_to_combinatory_python/
By niki at 2:36 a.m. on Nov. 20, 2008
I suppose that ω combinator in Python is
lambda x: x(x) right?
By James Tauber at 2:52 a.m. on Nov. 20, 2008
No, that's the M combinator.
ω = M(M)
Note that Eric defines ω as (λ x. x x) (λ x. x x)
The (λ x. x x) part is M.
By Marty Alchin at 8:41 a.m. on Nov. 20, 2008
Soooo..... let me get this straight. Lambda calculus is the basis for computer programming, especially in functional languages like our beloved Python. And by understanding lambda calculus we can understand how computer programs work. But by your own admission, when learning programming, we learn the concepts you've presented without ever needing to learn lambda calculus. What additional benefit do we gain by learning this after the fact?
To put it more simply, if lambda calculus is a means to an end (which I expect it is for those programmers who, like me, don't have scholarly intentions), and I'm already at the end (understanding programming), what do I stand to gain by learning lambda calculus? No, I'm not cutting you down at all, nor am I implying that you're forcing this down my throat. I'm honestly curious if there's some greater understanding I'm missing out on because I've never been taught this stuff.
By Atamert Ölçgen at 11:01 a.m. on Nov. 20, 2008
I don't think understanding how programs work and understanding how programming languages work are the same thing.
@Eric: <em>Cutting down the formality</em> and <em>exporing</em> are VERY VERY important for learning IMHO. You can always look up formal definitions from books or web, but if you don't walk through things you can absorb limited information.
By Scott Johnson at 12:03 a.m. on Nov. 21, 2008
Agreed. I like the informality of the post, especially for the topic. Great post, Eric.
By Matt Eggers at 3:20 p.m. on Dec. 1, 2008
I agree with everybody here. Lambda Calculus for me was so difficult to comprehend since a lot of it had already been innate. I still struggle with func. programming though (colon, right parenthesis). It confused me greatly. I came across this site looking for a definition of the substitution operator (/) and found this quaint post on the subject. Could've used this back in the school days. Very concise, and full of concrete examples. Something that is tough to do when describing the lambda calculus.
PS:
Alonzo Church proved that lambda calculus and Turing machines are synonymous in the functions that they can compute. Turing machines are a bit more concrete and "machine level" if you want to expand your horizons and really appreciate what a the computer does, look into those. JSTOR is a fun place to start.
By Adam at 11:19 a.m. on Nov. 20, 2008
I realise you probably know this but you post makes it sound a little like lambda functions with multiple arguments:
>>> (lambda a,b: a+b) (4,3)
7
are not valid python syntax.
By Zachary Voase at 1:03 p.m. on Nov. 20, 2008
Only within the lambda calculus (as in λ) is it invalid. Python's lambdas aren't true lambda functions, they're just anonymous.
By James Tauber at 1:10 p.m. on Nov. 20, 2008
One nit: I wouldn't say "Thanks to a technique called currying, however, we can express functions with infinite numbers of arguments." I think you really just mean functions with any number of arguments.
By Tony Garnock-Jones at 4:41 p.m. on Nov. 20, 2008
Although, given omega and friends, you can make functions which *accept* an infinite number of arguments :-)
By Tony Garnock-Jones at 4:44 p.m. on Nov. 20, 2008
If any readers find this stuff appetising at all, they might like to check out a book called The Structure and Interpretation of Computer Programs (full text available for free at http://mitpress.mit.edu/sicp/). It covers the topics Eric introduces above, and by the end of the book leaves you not just with a very versatile and practical toolkit but with a different perspective on just what computers are, what they do, and what programming is.
By Jeremy James at 5:13 p.m. on Nov. 20, 2008
Thank you for this post. I tend to partition my thinking too much like so: Mathematics | Scheme | Python. This helps bridge the gap a bit.
Can you comment on some of the noise from the python community about lambda being unnecessarily obfuscatory for most tasks?
By Dave K at 10:53 p.m. on Dec. 1, 2008
@Marty Alchin You'd better be darn happy those academic types spend time on this wacky stuff because without it you'd have no computer at all.
By wholesale jewelry at 1:51 a.m. on May 5, 2009
good site thanks alot,i hope u can update it often,
i will visit ur site often too.
By ben10 oyunları at 2:57 a.m. on May 25, 2009
It covers the topics Eric introduces above, and by the end of the book leaves you not just with a very versatile and practical toolkit
By wow at 7:28 p.m. on May 27, 2009
Very concise, and full of concrete examples. Something that is tough to do when describing the lambda calculus.
By wow gold at 4:33 a.m. on June 13, 2009
What you said is really right, I agree with you
By injection molding at 9:25 p.m. on June 13, 2009
nice blog site!
By sexy Lingerie at 8:01 p.m. on June 22, 2009
at least when trying to gauge raw performance. Using a high number of concurrent requests can also be problematic depending on the web server and how it is configured.
By jordan shoes at 12:57 a.m. on June 25, 2009
good site thanks alot,i hope u can update it often,
i will visit ur site often too.
By jordan shoes at 12:58 a.m. on June 25, 2009
Only within the lambda calculus (as in λ) is it invalid. Python's lambdas aren't true lambda functions, they're just anonymous.
By ugg boots at 12:58 a.m. on June 25, 2009
What you said is really right, I agree with you
By nike shoes at 12:59 a.m. on June 25, 2009
What you said is really right, I agree with you
By tiffany jewellery at 12:59 a.m. on June 25, 2009
Very concise, and full of concrete examples. Something that is tough to do when describing the lambda calculus.