The lambda calculus (λ-calculus) is a formal system for expressing computation through function abstraction and application; it is the mathematical foundation of every functional programming language.
The untyped λ-calculus has exactly three syntactic forms:
-
Variable
$x$ — a name standing for a value -
Abstraction
$\lambda x., e$ — a function with parameter$x$ and body$e$ -
Application
$e_1; e_2$ — apply function$e_1$ to argument$e_2$
Application is left-associative:
Abstraction extends as far right as possible:
A variable not under any enclosing
The core computation rule — substitute the argument for the parameter:
A term with no β-redex is in β-normal form.
If
η-equivalence captures the idea that a function is determined entirely by its behaviour on inputs.
If
Consequence: if a term has a normal form, that normal form is unique (up to α-equivalence). Reduction order does not affect the result, only whether it terminates.
| Strategy | When to reduce | FP examples |
|---|---|---|
| Normal order | Outermost redex first | Haskell (lazy) |
| Applicative order | Innermost redex first | OCaml, Racket (strict) |
| Call-by-name | Substitute without evaluating arg | Haskell thunks |
| Call-by-value | Evaluate arg before substituting | Most languages |
| Call-by-need | Call-by-name + memoise | Haskell default |
Normal order is complete (finds a normal form if one exists); applicative order may diverge even
when a normal form exists (e.g. (λx.y)((λx.xx)(λx.xx)) — the argument diverges but is never
needed).
The Y combinator is the canonical fixed-point combinator:
It satisfies
For call-by-value (applicative order) evaluation use the Z combinator (also called the
call-by-value Y):
Natural numbers encoded as higher-order functions (
Every λ-term (with no free variables) can be translated into a combinatorially complete basis of three constants, with no variable binding:
Note
The class of functions computable by the λ-calculus equals the class computable by a Turing machine, and both equal the class of general recursive (μ-recursive) functions. This is an empirical thesis — no counterexample has been found, and every proposed model of computation turns out to be equivalent.
| λ-calculus concept | FP language construct |
|---|---|
| Anonymous function / lambda literal | |
| Application |
Function call f(a) or f a
|
| β-reduction | Evaluation of a call (substitution step) |
| η-equivalence | Point-free definition: f = g when f x = g x
|
| Church numeral |
An n-fold fmap / iterator |
| Y combinator |
fix :: (a -> a) -> a in Haskell; letrec in Scheme |
| Z combinator | Anonymous recursion in strict languages |
| SKI translation | Point-free combinators ((.), const, id) |
| Normal order | Lazy evaluation (call-by-need) |
| Applicative order | Strict evaluation (call-by-value) |
| Simply typed λ-calculus | Hindley-Milner type inference |
| System F (polymorphic λ) |
forall-quantified types; Rank2Types in Haskell |
Every functional language is — at some level — a typed variant of the λ-calculus with syntactic sugar. Haskell's core language (GHC Core / System FC) is a typed λ-calculus.
→ FP track: 31. Computation Models and λ-Calculus | 1. Function | 3. Equational Reasoning | 4. Composition
| Resource | Link |
|---|---|
| CTFP blog — Types and Functions | Part 1 Ch 2 |
| CTFP blog — Function Types | Part 1 Ch 9 |
| CTFP LaTeX source Ch 1.2 | src/content/1.2/ |
| CTFP LaTeX source Ch 1.9 | src/content/1.9/ |
- Category — the category Hask where types are objects and λ-abstractions are morphisms
- Types & Functions — the FP interpretation of the typed λ-calculus
- Adjunction — currying ($A \times B \to C ;\cong; A \to (B \to C)$) is the canonical adjunction; it is the λ-calculus abstraction/application duality
-
F-Algebra — the fixed-point interpretation of the Y combinator;
$Y f = \mu (\lambda x. f,x)$