The rules are cheap; their consequences are the whole point.
Uniqueness (Church). If $\Gamma\vdash t:A$ and $\Gamma\vdash t:B$ then $A=B$ — checking is deterministic.
Subject reduction. If $\Gamma\vdash t:A$ and $t\to_\beta t'$ then $\Gamma\vdash t':A$ — types survive computation. Engine: the substitution lemma.
Strong normalization (Tait 1967). Every well-typed term halts — no infinite $\to_\beta$ sequence.
Consequence: $\Omega=(\lambda x.\,x\,x)(\lambda x.\,x\,x)$ and the $Y$-combinator are untypable. STLC trades Turing-completeness for guaranteed termination — and type-checking is decidable.
ch term \x. x x
Watch inference fail live: unifying $\alpha$ with $\alpha\to\beta$ trips the occurs check — the REPL reports “Cannot unify α with α → β”. Self-application has no simple type, so neither $\Omega$ nor $Y$ (which is built from self-application) does.
Church vs Curry: two readings, one system
Church style
Variables carry their type: $\lambda x{:}A.\,t$. Every term has at most one type. Typing is checking. — modern kernels.
Curry style
Bare untyped terms; a type is assigned after the fact. A term may have many types. Typing is inference.
Related by type-erasure $|\cdot|$. Organizing fact: the principal type. The identity $\lambda x.\,x$ has infinitely many types, all instances of one most-general $\alpha \to \alpha$.
ch term \p. p
Algorithm W, live: the Curry principal type $\alpha\to\alpha$; then ch lean \p. p for the Church-style Lean term fun p => p : P → P — one object, two readings, related by erasure.
Principal-type theorem (Hindley 1969, Milner 1978): computable by unification — the heart of Hindley–Milner inference in ML, Haskell, Lean's elaborator.
The Curry–Howard correspondence
The conceptual centre: a dictionary between logic and computation.
theorem trans_imp {P Q R : Prop} : (P → Q) → (Q → R) → P → R :=
fun f g p => g (f p)
“Chaining implications” and “composing functions” are one operation. The proof is the program.
prove (P -> Q) -> (Q -> R) -> P -> R
Build it yourself with intro/apply/exact; qed prints exactly $\lambda f\,g\,p.\,g\,(f\,p)$ and its type.
Peirce's law has no proof term
$\,((P\to Q)\to P)\to P\,$ is a classical tautology, yet no closed STLC term inhabits it. Try to build one and you get stuck: with $P,Q$ atomic, no rule makes a $Q$.
theorem peirce {P Q : Prop} : ((P → Q) → P) → P :=
fun h => Classical.byContradiction (fun hnp => hnp (h (fun hp => absurd hp hnp)))
Delete Classical and it fails to type-check. Curry–Howard yields intuitionistic proofs; excluded middle is an axiom you opt into, not a theorem.
Types are not (quite) sets
Read a type as the set of its closed normal terms: $[\![A\times B]\!]$ a product, $[\![A+B]\!]$ a disjoint union, $\bot=\varnothing$. For STLC this is honest. But it breaks three ways:
Proof relevance. Elements are proofs; $a\equiv b$ (computes to) $\ne$ $a=b$ (a theorem, an inhabitant of an identity type).
No set of all sets. $\mathsf{Type}:\mathsf{Type}$ is inconsistent — Girard's paradox (Hurkens 1995). Fix: universe hierarchy $\mathsf{U}_0:\mathsf{U}_1:\cdots$.
Constructive existence. An inhabitant of $\sum_{x:A}B(x)$ carries an actual witness.
Install the caveat the same hour as the intuition — each break motivates something later.
A first look at dependent types
Let a type depend on a value — e.g. length-indexed vectors $\mathsf{Vec}\,A\,n$. Two constructors:
$\Pi$-type $\;\prod_{x:A}B(x)\;$ — result type varies with input; realizes $\forall x{:}A.\,B(x)$. Constant $B$ = ordinary $A\to B$.
$\Sigma$-type $\;\sum_{x:A}B(x)\;$ — pair $\langle a,b\rangle$ with $b:B(a)$; realizes the witness-carrying $\exists x{:}A.\,B(x)$, with $\pi_1\langle a,b\rangle=a$.
A theorem like $\mathsf{cons}: A\to\mathsf{Vec}\,A\,n\to\mathsf{Vec}\,A\,(n{+}1)$ becomes a typing. Barendregt's $\lambda$-cube organizes the design space; its apex $\lambda C$ (Calculus of Constructions) is the ancestor of Lean's and Rocq's CIC.
$\exists$ as a $\Sigma$ with a real witness
A constructive proof of “there is an $n$ with $n+n=4$” is a pair: the witness $2$, and evidence that $2+2=4$ — which is refl, since both sides compute to the same numeral.
∃-even : Σ ℕ (λ n → n + n ≡ 4)
∃-even = 2 , refl
Its first projection returns $2$ — exactly what a classical non-emptiness proof cannot give you. In Martin-Löf type theory, $\mathbb{N}$-elimination is mathematical induction, now a primitive term former.
Why type theory underlies modern provers
Small trusted kernel (de Bruijn criterion) — proofs sound even if tactics are buggy.
Computation is native — $2+2$ and $4$ are the same type by conversion.
Extraction — the proof is the algorithm.
Theorems are types — you prove by inhabiting.
Lean 4 · CIC · classical (Mathlib)
Rocq · CIC + SProp · constructive core
Agda · predicative MLTT · constructive
Mizar · Tarski–Grothendieck set theory · no proof terms
Three type theories, one set theory — an engineering choice, not a coronation. Mizar verifies deep mathematics with no proof terms at all.
Run it yourself
See the correspondence — don't take it on faith. In the browser Lambda Lab, view a proof term and open it in Live Lean:
lean imp_comp
prints theorem imp_comp {P Q R : Prop} (f : P → Q) (g : Q → R) : P → R := fun p => g (f p) — exactly $\lambda f\,g\,p.\,g\,(f\,p)$ — with a live.lean-lang.org link. For Peirce's law,
kb intuitionistic
explains why it needs a classical principle — then let the lab settle it live:
ch type '((P -> Q) -> P) -> P'
reports Peirce's law uninhabited: exhaustive search finds no closed term. (Desktop lab only: ch verify re-checks the emitted Lean against a local Lean toolchain.)
Church vs Curry, principal types; Curry–Howard: provability = inhabitation.
Types $\approx$ sets, until proof-relevance, Girard's paradox, constructive $\exists$.
$\Pi/\Sigma$ dependent types, MLTT, and four provers on three type theories + one set theory.
Pierce, TAPL · Sørensen–Urzyczyn, Curry–Howard Isomorphism · Girard–Lafont–Taylor, Proofs and Types · Wadler, Propositions as Types · Martin-Löf, Intuitionistic Type Theory · the four-prover artifacts at github.com/nasqret/vietnam2026