Lambda Calculus
2026-08-19 09:30
They looked like a curiosity.
This unit cashes them in.
No primitive booleans.
No primitive integers.
Everything here is a λ expression you can expand and reduce.
zero and succA truth value’s whole job is to choose between two alternatives.
That is what a selector does.
The condition is the last argument, not the first.
In most languages if is a control structure and booleans are a primitive type.
Here both are ordinary functions.
| X | NOT X |
|---|---|
| FALSE | TRUE |
| TRUE | FALSE |
| X | Y | X AND Y |
|---|---|---|
| FALSE | FALSE | FALSE |
| FALSE | TRUE | FALSE |
| TRUE | FALSE | FALSE |
| TRUE | TRUE | TRUE |
X ? Y : FALSE gives def and = λx.λy.((x y) false)
| X | Y | X OR Y |
|---|---|---|
| FALSE | FALSE | FALSE |
| FALSE | TRUE | TRUE |
| TRUE | FALSE | TRUE |
| TRUE | TRUE | TRUE |
X ? TRUE : Y gives def or = λx.λy.((x true) y)
If and’s first operand is false, the second is never substituted anywhere.
So it is never evaluated.
Nothing in the definition asked for that.
An arbitrary integer is that number of successors of zero.
Each succ builds a pair function with false first and the original number second.
A number is a structure. Its nesting depth is its value.
For any \(\lambda s.((s\ false)\ \langle number\rangle)\), applying it to select_first gives false:
Note the direction: the number is applied to the selector.
Numbers are functions with selector arguments.
select_second strips a layer:
Not a representation of a number.
When we use pred we must be careful to check for a zero argument.
Choose a representation so the operations become easy.
Then define them and verify by reduction.
Numbers being pairs is what makes pred possible at all.
instead of
A function is applied first to the nearest argument on the right.
Still removable. Always.
def cond = λe1.λe2.λc.((c e1) e2)
def true = select_first
def false = select_second
def not = λx.((x false) true)
def and = λx.λy.((x y) false)
def or = λx.λy.((x true) y)
def zero = identity
def succ = λn.λs.((s false) n)
def iszero = λn.(n select_first)
def pred = λn.(((iszero n) zero) (n select_second))We started with a language containing only functions.
We now have booleans and integers.
Not simulated — built. Every definition expands to pure λ terms.
succ and pred step by one.
No addition. No multiplication. No comparison.
Each needs to repeat an operation — and repetition needs recursion.
Recursion and Arithmetic closes the gap.
It turns out recursion is genuinely hard to get here: a definition mentioning its own name cannot work, because a name is an abbreviation that expands.
The way out is the paradoxical combinator.
Lambda Calculus · Conditions, Booleans and Integers