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.