Beta. Content is under active construction and has not been peer-reviewed. Report errors on GitHub.Disclaimer

Foundations

Lambda Calculus

Lambda calculus is the simplest model of computation: just variables, abstraction, and application. It is equivalent to Turing machines in power, and it is the foundation of functional programming, type theory, and the Curry-Howard correspondence.

CoreTier 2Stable~45 min
0

Why This Matters

Lambda calculus is one of the two foundational models of computation (the other being Turing machines). It strips computation down to three operations: naming a variable, defining a function, and applying a function to an argument. Despite this simplicity, it can express any computable function.

Lambda calculus matters for three reasons. First, it is the theoretical foundation of functional programming (Haskell, ML, Lisp). Second, when you add types, it becomes the foundation of type theory and proof assistants like Lean and Coq. Third, the Curry-Howard correspondence says that typed lambda terms are proofs: programming and proving are the same activity in different notation.

Core Definitions

Definition

Lambda Term (Untyped)

The set of lambda terms Λ\Lambda is defined inductively:

  1. Variable: xΛx \in \Lambda for any variable xx.
  2. Abstraction: if MΛM \in \Lambda and xx is a variable, then (λx.M)Λ(\lambda x.\, M) \in \Lambda. This denotes a function with parameter xx and body MM.
  3. Application: if M,NΛM, N \in \Lambda, then (MN)Λ(M\, N) \in \Lambda. This denotes applying function MM to argument NN.

Nothing else is a lambda term. There are no numbers, no booleans, no data structures. Everything is built from these three forms.

Definition

Free and Bound Variables

In λx.M\lambda x.\, M, the variable xx is bound. An occurrence of xx in MM that is not inside another λx.\lambda x.\, \ldots is bound by this abstraction. A variable occurrence is free if it is not bound by any enclosing λ\lambda.

Example: in λx.(xy)\lambda x.\, (x\, y), xx is bound and yy is free.

Definition

Beta-Reduction

Beta-reduction is the computation rule of lambda calculus:

(λx.M)NβM[x:=N](\lambda x.\, M)\, N \to_\beta M[x := N]

where M[x:=N]M[x := N] means "substitute NN for every free occurrence of xx in MM" (with appropriate renaming to avoid variable capture). This is function application: apply the function λx.M\lambda x.\, M to the argument NN by substituting NN for xx in the body MM.

Definition

Normal Form

A lambda term is in normal form if no beta-reduction can be applied to it or any of its subterms. A term in normal form is "fully computed." Not every lambda term has a normal form; for example, Ω=(λx.xx)(λx.xx)\Omega = (\lambda x.\, x\, x)(\lambda x.\, x\, x) reduces to itself forever.

Church Encodings

Lambda calculus has no built-in data types, but you can encode them as lambda terms.

Church booleans:

true=λt.λf.t\text{true} = \lambda t.\, \lambda f.\, t false=λt.λf.f\text{false} = \lambda t.\, \lambda f.\, f

A boolean is a function that takes two arguments and returns one of them. Conditionals come for free: ifbthenMelseN\text{if}\, b\, \text{then}\, M\, \text{else}\, N is just bMNb\, M\, N.

Church numerals:

0ˉ=λf.λx.x\bar{0} = \lambda f.\, \lambda x.\, x 1ˉ=λf.λx.fx\bar{1} = \lambda f.\, \lambda x.\, f\, x 2ˉ=λf.λx.f(fx)\bar{2} = \lambda f.\, \lambda x.\, f\, (f\, x) nˉ=λf.λx.fnx\bar{n} = \lambda f.\, \lambda x.\, f^n\, x

A numeral nˉ\bar{n} is a function that takes ff and xx and applies ff to xx exactly nn times. Addition is λm.λn.λf.λx.mf(nfx)\lambda m.\, \lambda n.\, \lambda f.\, \lambda x.\, m\, f\, (n\, f\, x). Multiplication is λm.λn.λf.m(nf)\lambda m.\, \lambda n.\, \lambda f.\, m\, (n\, f).

Main Theorems

Theorem

Church-Rosser Theorem (Confluence)

Statement

If a lambda term MM reduces to both N1N_1 and N2N_2 (by possibly different sequences of beta-reductions), then there exists a term N3N_3 such that both N1N_1 and N2N_2 reduce to N3N_3.

If MβN1 and MβN2, then N3 such that N1βN3 and N2βN3.\text{If } M \twoheadrightarrow_\beta N_1 \text{ and } M \twoheadrightarrow_\beta N_2, \text{ then } \exists N_3 \text{ such that } N_1 \twoheadrightarrow_\beta N_3 \text{ and } N_2 \twoheadrightarrow_\beta N_3.

Intuition

It does not matter which reduction you perform first. All paths eventually converge. If a normal form exists, it is unique. This means that the "answer" a lambda term computes (if it terminates) does not depend on the evaluation strategy.

Proof Sketch

The standard proof uses the Tait-Martin-Lof method of parallel reductions. Define a relation \Rightarrow (parallel reduction) that reduces all redexes simultaneously. Show that \Rightarrow has the diamond property: if MN1M \Rightarrow N_1 and MN2M \Rightarrow N_2, then there exists N3N_3 with N1N3N_1 \Rightarrow N_3 and N2N3N_2 \Rightarrow N_3. Then β\twoheadrightarrow_\beta is the transitive closure of \Rightarrow, and the diamond property extends to the transitive closure.

Why It Matters

Confluence guarantees that lambda calculus is a well-defined computational model. The result of a computation does not depend on the order of evaluation. This is why pure functional programs are deterministic (in the absence of side effects) and why equational reasoning about programs is sound.

Failure Mode

Confluence holds for pure lambda calculus. Adding side effects (mutable state, I/O) or unrestricted recursion combinators can break it. In typed lambda calculi, confluence typically still holds, but normalization (every term reaches a normal form) also holds, which is a stronger property.

The Church-Turing Thesis

Alonzo Church and Alan Turing independently defined computability in the 1930s: Church via lambda calculus, Turing via Turing machines. They proved that the two models compute exactly the same class of functions.

The Church-Turing thesis (not a theorem, but a widely accepted principle) states: every effectively computable function is computable by a Turing machine (equivalently, expressible in lambda calculus). No physically realizable computational model has been shown to exceed this boundary.

Simply Typed Lambda Calculus

The untyped lambda calculus allows self-application (xxx\, x), which leads to non-termination. The simply typed lambda calculus (STLC) restricts terms with types to guarantee termination.

Definition

Simple Types

Types are built from base types (α,β,\alpha, \beta, \ldots) using the function type constructor:

τ::=ατ1τ2\tau ::= \alpha \mid \tau_1 \to \tau_2

A term M:τ1τ2M : \tau_1 \to \tau_2 is a function taking inputs of type τ1\tau_1 and producing outputs of type τ2\tau_2.

In STLC, every well-typed term has a normal form (strong normalization). Self-application xxx\, x is not typable, because xx would need type τσ\tau \to \sigma and type τ\tau simultaneously, which requires τ=τσ\tau = \tau \to \sigma, an infinite type.

The trade-off: STLC is not Turing-complete. It can only express total (terminating) functions. To recover full computational power, you add recursion (a fixpoint combinator), but then you lose guaranteed termination.

Curry-Howard Correspondence

The Curry-Howard correspondence is the observation that types correspond to propositions and terms correspond to proofs:

Lambda calculusLogic
Type ABA \to BProposition A    BA \implies B
Term of type ABA \to BProof that AA implies BB
Function applicationModus ponens
Lambda abstractionImplication introduction

A type is "inhabited" (has a term of that type) if and only if the corresponding proposition is provable. This correspondence is the foundation of proof assistants: to prove a theorem, you construct a term of the corresponding type.

Common Confusions

Watch Out

Lambda calculus is not about Greek letters

The λ\lambda is just notation for function definition. λx.x+1\lambda x.\, x + 1 is the function that adds 1 to its input. In Python, this is lambda x: x + 1. The theoretical significance is that function definition is the only primitive; everything else is derived.

Watch Out

Not every lambda term terminates

Ω=(λx.xx)(λx.xx)\Omega = (\lambda x.\, x\, x)(\lambda x.\, x\, x) beta-reduces to itself, looping forever. The untyped lambda calculus is Turing-complete, which means non-termination is possible. Simply typed lambda calculus guarantees termination but is weaker.

Exercises

ExerciseCore

Problem

Reduce the following lambda term to normal form: (λx.λy.x)ab(\lambda x.\, \lambda y.\, x)\, a\, b.

ExerciseCore

Problem

Write the Church encoding of the successor function succ\text{succ}, which takes a Church numeral nˉ\bar{n} and returns n+1\overline{n+1}.

ExerciseAdvanced

Problem

Explain why the self-application term λx.xx\lambda x.\, x\, x cannot be typed in the simply typed lambda calculus.

References

Canonical:

  • Barendregt, The Lambda Calculus: Its Syntax and Semantics (1984)
  • Church, "An Unsolvable Problem of Elementary Number Theory" (1936)

Accessible:

  • Pierce, Types and Programming Languages (2002), Chapters 5-9
  • Hindley & Seldin, Lambda-Calculus and Combinators (2008)

Next Topics

Last reviewed: April 2026

Builds on This

Next Topics