When Cantor’s set theory – what we now call naive set theory – was shown to have problems in
the form of Russell’s paradox, there were many different attempts to salvage the theory. In
addition to the axiomatic approaches that we’ve looked at (ZFC and NBG), there were attempts
by changing the basis of set theory – discarding sets in favor of something similar, but
with restrictions that avoid the problems of naive set theory. Today, I’m going to
talk about an example of the latter approach, called type theory. Type theory is a
very different approach from what we’ve seen before, and one which is particularly
useful and interesting to people in my neck of the woods.
What type theory does is create a new kind of collection object, called a type. The
idea behind types is to create a stratification, similar to the idea behind ordered logics. In
first order logic, you can only reason about primitive atoms, not about predicates. In second order
logic, you can reason about atoms and first-order predicates, but not second-order predicates. And so on.
In type theory, you do roughly the same kind of thing, but you do it even more strictly. A first-order type can only contain atoms – primitive values that are not types. (Some versions of type theory call
these ur-elements.) A second order type can only contain first-order types as elements. And so on. So type are strictly stratified: each level or stratum of types has members of the next lower stratum
of types.
Using the basic idea above, of stratified types, we can define the simplest version of type theory,
called ST, with a collection of axiom schema. For the axiom schema, there’s a convention in how
they’re written. Each axiom makes statements about types of two levels: a base level, and its successor.
Variables that range over types of the base level are written as lower-case letters; variables that range
over the next level are written as lower-case letters followed by “‘”. So if “a” is a variable ranging
over level n types, “b'” is a variable ranging over level n+1 types.
ST has 4 axiom schemas:
- Axiom of Identity: x=y ⇔ ∀z'[x ∈ z’ ⇔ y∈z’]: two values
x and y are the same if and only if every type that contains x also contains y. It’s interesting
to compare this one to set theory; it’s exactly inverse. In set theory, two values are the same if they have the same members; in type theory, two values are the same if they’re members of the same types. - Axiom of Extensionality: ∀x[x∈y’ ⇔ x∈z’] ⇒ y’ = z’. This
is very much the same idea as equality in set theory. Two types are equal as long as they have the
same members. So in type theory, we get both the upwards and downwards properties of equality. - Axiom of Comprehension: If φ is a first-order predicate, then: ∃z’: ∀x[x∈z’ ⇔ φ(x)]. Basically the same as the comprehension axiom of set theory,
modified to include the stratification of types. It says that we can define a level n+1 type using a predicate over level n types. - Axiom of Infinity: There exists a relation, “<“, which
ranges over pairs of atoms, which is total, irreflexive, transitive, and strongly connected, such that ∀x,y[x≠y ⇒ [x<y ∨ y<x]]. The version of the axiom of infinity in type theory is a bear. Instead of being a direct construction like it is in ZF, it’s an indirect statement. What it says is that “<” is a total relation, which imposes a closed total order on the atoms. More, it requires that the domain
and the codomain of < are the same: so if a value can appear on the right side of “<” (saying that there’s something smaller than it), it must also appear on the left side of “<” (saying that there’s something larger than it.) For this relation over the atoms to be possible, there must be at least one level 0 infinite type. So this does really assert the existence of an infinite
type; but it does it indirectly, via requiring a relation which can only be satisfied by an infinite type. (Note: originally, I left “total” out of this definition; without totality, it doesn’t necessarily imply the existence of an infinite set! Thanks to commenters for pointing this out.)
If you look at this structure: atoms, stratified types, and the axioms, it should be clear that most
of the things that we can do using axiomatic set theory can also be done in ST. You can’t mix
things like x and {x} like you could in set theory, which does place some limits on you – but the
fact that you’re allowed to have non-type primitive atoms goes a long way towards fixing that. The
downside there is clear: while you can generally say the same things in set theory and type theory,
the statements are often a lot more complex in terms of type theory.
Type theory is clearly more complicated than good old set theory. So what does that complexity buy
you? Most importantly, it gets rid of Russell’s paradox. Since no type can contain members of its own type
level, you can’t construct anything like “The types of all types that don’t contain themselves as
members.”; there’s just no way of saying that. Axiomatic theory does the same thing – but it does it by,
essentially, creating only two levels: proper classes and sets, and sharply limiting the ability to do
reasoning about proper classes. Type theory restricts the structures you can build at any level, but by
doing so, it allows to create a hierarchy of types, each of which is first class, capable of membership,
and fully amenable to formal reasoning.
In addition, logic using type theory can be quite elegant. A lot of work in logic is done in terms of
stratified logics, and type theory fits quite naturally with stratified logic. Plus, type theory and logic
together are the basis of an awful lot of theoretical computer science. ST, and its more powerful
children, form the basis of types in λ-calculus, which in turn is the source of the whole idea of
types in programming languages. In fact, the parametric type system which was added to Java not too long
ago has its semantics formally specified using a relative of ST.