I enjoy reading about formal logic as an occasional hobby. However, one thing keeps tripping me up: I seem unable to understand what’s being referred to when the word “type” (as in type theory) is mentioned.
Now, I understand what types are in programming, and sometimes I get the impression that types in logic are just the same thing as that: we want to set our formal systems up so that you can’t add an integer to a proposition (for example), and types are the formal mechanism to specify this. Indeed, the Wikipedia page for type theory pretty much says this explicitly in the lead section.
However, it also goes on to imply that types are much more powerful than that. Overall, from everything I’ve read, I get the idea that types are:
- like types in programming
- something that is like a set but different in certain ways
- something that can prevent paradoxes
- the sort of thing that could replace set theory in the foundations of mathematics
- something that is not just analogous to the notion of a proposition but can be thought of as the same thing (“propositions as types”)
- a concept that is really, really deep, and closely related to higher category theory
The problem is that I have trouble reconciling these things. Types in programming seem to me quite simple, practical things (alhough the type system for any given programming language can be quite complicated and interesting). But in type theory it seems that somehow the types are the language, or that they are responsible for its expressive power in a much deeper way than is the case in programming.
So I suppose my question is, for someone who understands types in (say) Haskell or C++, and who also understands first-order logic and axiomatic set theory and so on, how can I get from these concepts to the concept of type theory in formal logic? What precisely is a type in type theory, and what is the relationship between types in formal mathematics and types in computer science?
(I am not looking for a formal definition of a type so much as the core idea behind it. I can find several formal definitions, but I’ve found they don’t really help me to understand the underlying concept, partly because they are necessarily tied to the specifics of a particular type theory. If I can understand the motivation better it should make it easier to follow the definitions.)
tl;dr Types only have meaning within type systems. There is no stand-alone definition of “type” except vague statements like “types classify terms”. The notion of type in programming languages and type theory are basically the same, but different type systems correspond to different type theories. Often the term “type theory” is used specifically for a particular family of powerful type theories descended from Martin-Löf Type Theory. Agda and Idris are simultaneously proof assistants for such type theories and programming languages, so in this case there is no distinction whatsoever between the programming language and type theoretic notions of type.
It’s not the “types” themselves that are “powerful”. First, you could recast first-order logic using types. Indeed, the sorts in multi-sorted first-order logic, are basically the same thing as types.
When people talk about type theory, they often mean specifically Martin-Löf Type Theory (MLTT) or some descendant of it like the Calculus of (Inductive) Constructions. These are powerful higher-order logics that can be viewed as constructive set theories. But it is the specific system(s) that are powerful. The simply typed lambda calculus viewed from a propositions-as-types perspective is basically the proof theory of intuitionistic propositional logic which is a rather weak logical system. On the other hand, considering the equational theory of the simply typed lambda calculus (with some additional axioms) gives you something that is very close to the most direct understanding of higher-order logic as an extension of first-order logic. This view is the basis of the HOL family of theorem provers.
Set theory is an extremely powerful logical system. ZFC set theory is a first-order theory, i.e. a theory axiomatized in first-order logic. And what does set theory accomplish? Why, it’s essentially an embedding of higher-order logic into first-order logic. In first-order logic, we can’t say something like ∀P.P(0)∧(∀n.P(n)⇒P(n+1))⇒∀n.P(n) but, in the first-order theory of set theory, we can say ∀P.0∈P∧(∀n.n∈P⇒n+1∈P)⇒∀n.n∈P Sets behave like “first-class” predicates.
While ZFC set theory and MLTT go beyond just being higher-order logic, higher-order logic on its own is already a powerful and ergonomic system as demonstrated by the HOL theorem provers for example. At any rate, as far as I can tell, having some story for doing higher-order-logic-like things is necessary to provoke any interest in something as a framework for mathematics from mathematicians. Or you can turn it around a bit and say you need some story for set-like things and “first-class” predicates do a passable job. This latter perspective is more likely to appeal to mathematicians, but to me the higher-order logic perspective better captures the common denominator.
At this point it should be clear there is no magical essence in “types” themselves, but instead some families of type theories (i.e. type systems from a programming perspective) are very powerful. Most “powerful” type systems for programming languages are closely related to the polymorphic lambda calculus aka System F. From the proposition-as-types perspective, these correspond to intuitionistic second-order propositional logics, not to be confused with second-order (predicate) logics. It allows quantification over propositions (i.e. nullary predicates) but not over terms which don’t even exist in this logic. Classical second-order propositional logic is easily reduced to classical propositional logic (sometimes called zero-order logic). This is because ∀P.φ is reducible to φ[⊤/P]∧φ[⊥/P] classically. System F is surprisingly expressive, but viewed as a logic it is quite limited and far weaker than MLTT. The type systems of Agda, Idris, and Coq are descendants of MLTT. Idris in particular and Agda to a lesser extent are dependently typed programming languages.1 Generally, the notion of type in a (static) type system and in type theory are essentially the same, but the significance of a type depends on the type system/type theory it is defined within. There is no real definition of “type” on its own. If you decide to look at e.g. Agda, you should be quickly disabused of the idea that “types are the language”. All of these type theories have terms and the terms are not “made out of types”. They typically look just like functional programs.
1 I don’t want to give the impression that “dependently typed” = “super powerful” or “MLTT derived”. The LF family of languages e.g. Elf and Twelf are intentionally weak dependently typed specification languages that are far weaker than MLTT. From a propositions-as-types perspective, they correspond more to first-order logic.