Type theory is a branch of mathematical logic and theoretical computer science that studies systems of classifying terms according to the kinds of values they compute or denote. Originally developed to resolve paradoxes in naive set theory, it has evolved into a foundational framework for programming languages, proof assistants, and the formalization of mathematics. Type theory assigns types to expressions, ensuring that operations are applied only to compatible inputs, thereby preventing errors such as applying a function to an argument of the wrong kind. It underpins typed lambda calculi, which are central to functional programming and constructive logic.

1 Historical development

1.1 Origins in Russell's paradox

Type theory originated in the early 20th century as a response to Russell's paradox in naive set theory. Bertrand Russell discovered that the set of all sets that do not contain themselves leads to a contradiction. To avoid such paradoxes, Russell and Alfred North Whitehead introduced the ramified theory of types in their work *Principia Mathematica* (1910–1913). This theory stratified objects into a hierarchy of types, prohibiting self-membership and thereby eliminating the paradox.

1.2 Simple type theory (Church's simply typed lambda calculus)

In the 1940s, Alonzo Church developed the simply typed lambda calculus (STLC), which added types to the untyped lambda calculus. In STLC, every term is assigned a type, and functions can only be applied to arguments of the appropriate type. This system provided a foundation for higher-order logic and demonstrated that typing could prevent inconsistencies.

1.3 Intuitionistic type theory (Martin-Löf)

In the 1970s, Per Martin-Löf introduced intuitionistic type theory (also called constructive type theory). This system unified logic and computation by interpreting propositions as types and proofs as programs. It features dependent types, where types can depend on terms, enabling the formalization of mathematics in a constructive setting.

1.4 Calculus of constructions and the lambda cube

In the 1980s, Thierry Coquand and Gérard Huet developed the Calculus of Constructions, a higher-order typed lambda calculus that combines dependent types, type operators, and polymorphism. This system served as the basis for the proof assistant Coq. Around the same time, Henk Barendregt introduced the lambda cube, a three-dimensional classification of pure type systems based on the dimensions of polymorphism, dependent types, and higher-order types.

2 Basic concepts

2.1 Types and terms

In type theory, every term (expression) is associated with a type. A type is a classification that determines the set of values a term can assume and the operations that can be performed on it. For example, the term x might be of type Nat (natural numbers), and f might be of type Nat → Bool (a function from naturals to booleans). Types serve as static specifications of behavior.

2.2 Type formation rules

Type formation rules specify how to construct well-formed types. For instance, there are rules for forming function types (A → B), product types (A × B), sum types (A + B), and, in dependent type systems, dependent product types (Π x:A. B(x)) and dependent sum types (Σ x:A. B(x)). These rules are part of a formal system that defines the syntax of types.

2.3 Type judgments and contexts

A type judgment is an assertion of the form Γ ⊢ t : T, meaning that under the typing context Γ (a list of variable type assignments), the term t has type T. Contexts track the types of free variables. Typing derivation rules, such as the rules for application and abstraction, define how to infer judgments.

2.4 Subtyping and type polymorphism

2.4.1 Parametric polymorphism

Parametric polymorphism allows a term to have a type that is quantified over all types, such as ∀α. α → α. This enables the definition of functions that operate uniformly on arguments of any type, like the identity function. System F, introduced by Jean-Yves Girard, formalizes parametric polymorphism.

2.4.2 Ad hoc polymorphism (overloading)

Ad hoc polymorphism, or overloading, allows a function name to denote different implementations depending on the types of its arguments. In many programming languages, operators like + are overloaded for integers and floating-point numbers. Unlike parametric polymorphism, ad hoc polymorphism requires separate definitions for each type.

2.4.3 Subtype polymorphism

Subtype polymorphism allows a term of a subtype to be used wherever a supertype is expected. For example, if Dog is a subtype of Animal, then a Dog can be passed to a function expecting an Animal. Subtyping is common in object-oriented languages and can be formalized by a subsumption rule in the type system.

3 Major systems of type theory

3.1 Simply typed lambda calculus

3.1.1 Syntax and reduction rules

The simply typed lambda calculus (STLC) has types built from base types and function types. Terms include variables, lambda abstractions (λx:A. t), and applications (t1 t2). The primary reduction rule is β-reduction: (λx:A. t) s reduces to t[s/x] (substituting s for x in t). η-reduction and η-expansion are also possible.

3.1.2 Strong normalization

A key property of STLC is strong normalization: every well-typed term reduces to a unique normal form after a finite number of reduction steps, regardless of the reduction strategy. This ensures that the calculus is terminating and consistent as a logic.

3.2 System F and second-order lambda calculus

System F extends STLC with polymorphic types, allowing universal quantification over types. Terms can be abstracted over types (Λα. t) and applied to types (t[A]). This system can express data types like lists and trees via Church encoding. It is strongly normalizing and corresponds to second-order propositional logic via the Curry–Howard correspondence.

3.3 Dependent types

3.3.1 Dependent product and sum types

Dependent types allow types to depend on terms. The dependent product type Π x:A. B(x) represents functions whose output type can vary with the input value. The dependent sum type Σ x:A. B(x) represents pairs where the second component's type depends on the first. These constructs enable fine-grained specification, such as vectors of a given length.

3.3.2 Universe hierarchy

To avoid paradoxes like Girard's paradox, dependent type theories introduce a universe hierarchy: Type₀ : Type₁ : Type₂ : .... Each universe contains the (smaller) types of the previous level. This stratification ensures that types themselves form a well-founded hierarchy, similar to the treatment of sets in set theory.

3.4 Pure type systems

3.4.1 The lambda cube classification

Pure type systems (PTS) are a family of typed lambda calculi parameterized by the allowed dependencies between terms, types, and kinds. The lambda cube arranges these systems along three axes: polymorphism (terms depending on types), dependent types (types depending on terms), and higher-order types (types depending on types). The eight vertices include the simply typed lambda calculus, System F, and the Calculus of Constructions.

4 Relation to logic

4.1 Curry–Howard correspondence

4.1.1 Propositions as types

The Curry–Howard correspondence establishes an analogy between logic and computation: a proposition is interpreted as a type, and a proof of that proposition is a term of that type. Conjunction corresponds to product types, disjunction to sum types, implication to function types, and universal quantification to dependent product types.

4.1.2 Proofs as programs

Under this correspondence, constructing a proof is equivalent to writing a program that inhabits the corresponding type. Normalization of a term corresponds to cut elimination in logic. This principle underlies proof assistants, where proving a theorem is done by constructing a term in a typed lambda calculus.

4.2 Typed proof theory

4.2.1 Natural deduction with typing

Typed natural deduction extends Gentzen's natural deduction by assigning types (formulas) to each proof term. Typing rules correspond directly to inference rules (introduction and elimination). For example, implication introduction corresponds to lambda abstraction, and implication elimination corresponds to application.

4.2.2 Sequent calculus

Sequent calculus, also due to Gentzen, can be typed by assigning types to formulas and using a sequent Γ ⊢ Δ where all formulas are assigned types. The cut rule corresponds to substitution in typed lambda calculi, and cut elimination corresponds to the normalization of terms.

5 Applications in computer science

5.1 Programming languages

5.1.1 Static type checking and type inference

Static type checking analyzes program source code before execution to ensure type consistency, catching many errors at compile time. Type inference algorithms, such as Hindley–Milner type inference, automatically deduce types without requiring explicit annotations, enabling conciseness and safety (e.g., in ML and Haskell).

5.1.2 Type safety and memory management

A type-safe language prevents operations that could cause undefined behavior, such as applying arithmetic to a pointer. Type systems often interact with memory management: languages like Rust use ownership types to enforce memory safety without garbage collection, while garbage-collected languages rely on runtime checks for type safety.

5.2 Formal verification and proof assistants

5.2.1 Coq, Agda, and Lean

Proof assistants such as Coq, Agda, and Lean implement dependent type theories. Users write formal proofs by building terms; the system checks that these terms are well-typed, ensuring correctness. These tools are used to verify mathematical theorems and software correctness (e.g., the CompCert C compiler verified in Coq).

5.2.2 Dependent types in verification

Dependent types allow specifying precise invariants, such as array bounds checking at compile time. For example, a function that returns a vector of length n can be typed as Vec A n. This eliminates entire classes of runtime errors and is used in verifying critical systems.

5.3 Domain-specific type systems

5.3.1 Type systems for concurrent and distributed systems

Concurrent and distributed programming introduces challenges like race conditions and data consistency. Type systems such as session types enforce communication protocols, ensuring that messages are sent and received in the correct order. Linear types are used to manage resources in concurrent settings.

5.3.2 Gradual typing

Gradual typing allows mixing statically typed and dynamically typed code within the same program. It uses a special ? (dynamic) type and inserts runtime checks at boundaries. This approach, implemented in languages like TypeScript and Typed Racket, eases the adoption of static typing in existing dynamic codebases.

6 Philosophical and foundational issues

6.1 Type theory vs. set theory as a foundation

Both type theory and set theory can serve as a foundation for mathematics. Set theory is built on a single primitive (∈) and relies on stratified axioms, while type theory uses a hierarchy of types and computational constructs. Constructivists prefer type theory for its computational content and lack of impredicativity; classical mathematicians often favor ZFC set theory for its simplicity and strength.

6.2 Impredicativity and predicativity

Impredicative definitions (e.g., "the least upper bound of all real numbers") are allowed in classical set theory and higher-order type systems like System F. However, they can lead to paradoxes if unrestricted. Predicative systems forbid such definitions, requiring that types be constructed only from already existing ones, which aligns with constructive views.

6.3 Constructivity and identity types

Type theory provides a constructive account of equality through identity types (e.g., Id A a b). A proof of a = b is a witness that can be used for substitution. This contrasts with the extensional notion of equality in set theory. The nature of identity types is central to homotopy type theory and the discussion of propositional equality.

7 Contemporary research directions

7.1 Homotopy type theory (HoTT)

7.1.1 Univalence axiom

Homotopy type theory extends Martin-Löf type theory with the univalence axiom, which states that equivalence between types is equivalent to identity. This allows isomorphic structures to be treated as identical, enabling "transport" of properties across equivalences. HoTT provides a foundation for mathematics based on homotopy theory.

7.1.2 Higher inductive types

Higher inductive types generalize ordinary inductive types by allowing path constructors that define equalities. For example, the circle type has a base point and a loop path. These types enrich homotopical reasoning and allow the definition of spaces directly in type theory.

7.2 Categorical semantics

7.2.1 Cartesian closed categories

The simply typed lambda calculus has models in Cartesian closed categories (CCC), where objects correspond to types and morphisms to terms. The correspondence between STLC and CCCs is a classic example of categorical logic, providing a bridge between syntax and semantics.

7.2.2 Locally cartesian closed categories

Dependent type theories are modeled in locally Cartesian closed categories (LCCC), where every slice category is Cartesian closed. These categories support dependent product and sum types. The conceptual framework of categories with families and categories with attributes further formalizes the semantics.

7.3 Linear and substructural type systems

Linear types enforce that each variable is used exactly once, modeling resources that cannot be duplicated or discarded. Substructural type systems (affine, relevant, ordered) control usage through typing rules. They are applied to memory management, concurrency, and quantum computation, where resource discipline is critical.

8 Notable figures and works

8.1 Bertrand Russell and Alfred North Whitehead

Russell and Whitehead authored *Principia Mathematica* (1910–1913), which introduced the ramified theory of types to solve the paradoxes. Their work laid the groundwork for later type theories and formal logic.

8.2 Alonzo Church

Church introduced the simply typed lambda calculus (1940) and formulated Church's thesis. His work on the lambda calculus provided a formal system for computability and typed functions.

8.3 Per Martin-Löf

Martin-Löf developed intuitionistic type theory (1972, 1984), a constructive foundation for mathematics based on types. His system introduced dependent types and is the basis for many proof assistants.

8.4 Jean-Yves Girard

Girard discovered System F (1972) and the concept of linear logic. He also proved strong normalization for System F and contributed to the theory of cut elimination.

8.5 Thierry Coquand and Gérard Huet

Coquand and Huet created the Calculus of Constructions (1988), which combined dependent types and polymorphism. Their work directly led to the Coq proof assistant.

9 See also

  • Lambda calculus
  • Curry–Howard correspondence
  • Homotopy type theory
  • Proof assistant
  • Kind (type theory)

10 References and further reading

  • Barendregt, H. (1992). "Lambda Calculi with Types". *Handbook of Logic in Computer Science*.
  • Coquand, T., & Huet, G. (1988). "The Calculus of Constructions". *Information and Computation*.
  • Girard, J.-Y. (1972). "Interprétation fonctionnelle et élimination des coupures dans l'arithmétique d'ordre supérieur". Thèse.
  • Martin-Löf, P. (1984). *Intuitionistic Type Theory*. Bibliopolis.
  • Pierce, B. C. (2002). *Types and Programming Languages*. MIT Press.
  • Russell, B., & Whitehead, A. N. (1910–1913). *Principia Mathematica*. Cambridge University Press.
  • The Univalent Foundations Program. (2013). *Homotopy Type Theory: Univalent Foundations of Mathematics*. IAS.