Lambda Calculus
2026-08-19 09:00
You have written programs in an imperative language.
Variables, assignment, loops, arrays.
This unit works against that experience.
Remove the assignment statement.
What is left?
Then: where these ideas came from, and what the λ calculus is.
Every difference in this unit follows from a single decision:
what a name is allowed to mean.
Functional programming is an approach to programming based on function calls as the primary programming construct.
It forms a bridge between formal methods in computing and their application.
The reason it has such a clean theory is that it started as theory.
A calculator does arithmetic on numbers.
Its limitation: no way to generalise a calculation.
To reuse it with different values, re-enter the whole thing.
We write a program using names to stand for values in general.
Then run it with the names taking particular values from the input.
The program does not change. Only the input does.
Both styles agree so far.
A variable is a changeable association between a name and values.
The same name may be associated with different values.
A program is an expression — nested function calls:
Names are introduced only as formal parameters, and given values by calls supplying actual parameters.
Once bound, never rebound.
A name is only ever associated with one value.
To know what a name means imperatively, you must know when you are asking.
Functionally, you look at where it was bound.
Time does not enter.
T depends on X, X depends on Y, Y depends on T.
Any change in the sequence changes what happens.
Imperative languages have fixed execution orders.
Function calls cannot change values associated with shared names.
\[F(A(D),\ B(D),\ C(D))\]
The order of A(D), B(D), C(D) does not matter — none of them can change D.
There is no necessary execution order.
Programs still run in some order. It just does not affect the result.
Order does not affect the result.
It can affect whether evaluation terminates.
Unit 2 makes this precise. Unit 4 depends on it completely.
Summing N elements of A — not this:
Each call creates new local versions of A, I and N.
I > NThe variable that “changes” is really a sequence of values. Recursion makes it explicit.
This works because SUM can refer to itself by name.
In the pure λ calculus, a name is an abbreviation, not a reference.
Unit 4 is about getting recursion back.
No assignment means sub-structures cannot be changed one at a time.
Functional languages provide explicit representations for data structures.
No arrays. Nested structures like lists instead, defined recursively.
Calls get bigger. In exchange, the flow of data is visible.
Functional languages allow functions to be treated as values.
Many imperative languages let you pass a sub-program in.
Few let you pass one back.
If functions are values, a structure holding two things can be a function that, given a selector, returns one of them.
Data stops needing its own mechanism.
That is the whole content of unit 3.
true/false, and/or/not, names for truth values0 and the successor function, proofs by inductionUnit 3 builds the naturals exactly as Peano did.
Within these calculi:
Both properties we met earlier were already there.
Russell and Whitehead try to derive mathematics from logic.
Hilbert asks for a proof that it is consistent and complete.
Gödel: any system powerful enough to describe arithmetic is necessarily incomplete.
Each has simple primitives, simple structuring rules, and — crucially — a proof theory.
To each other, and to digital computers.
Church’s thesis: all descriptions of computability are equivalent.
Cannot be proved. Never yet contradicted.
Turing machines
symbol manipulation, assignment, time-ordered evaluation
λ calculus, recursive functions
structured function application, evaluation order independent
Two models of the same class — each looking like one of our two programming styles.
The halting problem is unsolvable — for Turing machines, and equally for λ expressions.
But Church–Rosser: if different evaluation orders terminate, the results are the same.
And one particular order is more likely to terminate than any other.
The λ calculus was a model of computation before it was a programming language.
That is why it can be minimal and still be enough.
Abstraction — generalise an expression by introducing names.
Application — evaluate it by giving names particular values.
No numbers. No booleans. No data structures. No control flow. No recursion.
Real languages are notation on top of this core.
Every addition — numbers, conditionals, data, recursion — can be explained by translating it back down.
That translation is what units 2 to 4 actually do.
Elements of Lambda Calculus stops motivating and starts defining.
Ending with selectors and pairs — the building blocks units 3 and 4 depend on.
Lambda Calculus · Introduction