8 The Lambda Cube: λ-cube
The λ-cube provides a systematic organization of types systems that captures a range of expressiveness, from the simply-typed lambda calculus (in The simply-typed lambda calculus λ-st) through the polymorphic lambda calculus (in The polymorphic lambda calculus λ-2), the higher-order lambda calculus (in The higher-order lambda calculus λ-ω), and up to λC, the calculus of constructions, which is the focus of this section.
8.1 Syntax
The basic idea of the structure of the λ cube is to eliminate the distinction between types and terms and then use typing judgments to control which classes of expression are allowed in type positions. To get started, we first just get rid of the distinction between types and terms using this syntax:
The first three expression forms are the familiar variables, lambda abstractions, and application expressions. The is the type of types, just as in The polymorphic lambda calculus λ-2, and is analgous, but one level up. That is, it represents the type of kinds or, expressions that have the type are expressions that themselves compute kinds.
The final expression form, , represents function types, but it is dependent. In its simplest form, the type , where does not appear free in , represents functions from to . In general, however, the variable can appear free in , meaning that the type of the result of the function can depend on the argument actually supplied to the function.
This notation specializes to the earlier type systems we considered; as an example, recall the function composition operator from the beginning of The polymorphic lambda calculus λ-2. Here’s the original version of the function:
In the new language, the and are not distinguished by the constructor, but a is the same thing as a where the argument has type . So, this is the composition operator in λ-cube:
We also adjust the syntax to require an extra set of parentheses and a colon to make it a little bit easier to read expressions (because other distinctions are removed).
Another example that’s worth considering is the identity function. Here it is:
This term is what you would expect, simply replacing the capital Λ with the lowercase λ and adding a . But consider its type:
This is a type that cannot be expressed with just the arrow. Or, in other words, this is a dependent type because the variable bound by the outer function type is used in its body. It is the same as the type but we can use for both the function type and for the type.
8.2 Typing Rules
If we restrict the rule so that both and are , then the resulting type system is equivalent to the simply-typed lambda calculus. Intuitively, this restriction means that our functions can accept arguments that are values, i.e., can be described by types, but not by kinds.
If we allow to be either or , but restrict so it can be only , we get the polymorphic lambda calculus, λ-2. This means that functions can now play the role of , expressions, accepting types, but always returning only a type. Various other restrictions in this spirit correspond to various other type systems in the literature.