Post 2


This will be the Second Post in the PLT section. It will introduce the Lambda Calculus for Types-Dependent-on-Types[λ ω ] (or atleast, a version of it) : The Motivation behind it; Its Semantics and Properties.

I expect the reader to be familiar with the basics of Lambda Calculus, Type Theory, and the System λ2, which is the Second-Order Typed Lambda Calculus.

Once again, I will use β to refer to singular and chained β-reductions.

MOTIVATION : Let’s start by motivating the need for (λ ω ) and seeing why (λ2) isn’t enough for sophisticated types. In order to see this, let’s briefly remind ourselves of the generating Grammars for the set of 𝕋2-types and (λ2) :

𝕋2 = 𝕍 | (𝕋2 𝕋2) | 𝕍:*.𝕋2

Λ 𝕋2 = V | λV:𝕋2. Λ 𝕋2 | Λ 𝕋2 Λ 𝕋2 | λ𝕍:*.Λ 𝕋2 | Λ 𝕋2 𝕋2

The λ2, as we can see, is great at dealing with Terms-Dependent-on-Types, by introducing the -type. This allows a term to "bind" to many different types. However, the bindings are relatively straightforward, and therefore, so are the -types.

An example is the definition of the ’Nat’-type :

α : * . (αα)αα

All elements of ‘Nat‘ will have this type, and can be constructed generally as : λα : * . λf : αα . λx : α . f(f(f(...(fx))))

It is easy to see that - f(f(f(...(fx)))) : α

So, λ2 gives us the ability to concisely write functions with terms for generic types. For instance, one could construct a generic identity function, and then simply substitute in the type and term (in that order), to make it act as an identity function for that specific Type. However, it doesn’t allow us to construct Types-Dependent-on-Types. The reason for this is in the 2nd-order application/abstraction rules in λ2 :

  1. ΓM:α:* . A, ΓB:*

    ΓMB : A[α:=B]

  2. Γ,α:*M:A

    Γλα : * . M:α:* . A

As on can see, the ΓB:* proposition from (appl 2 ) does not allow us to "bind" more complicated types than *. In addition, the cycle for this simplicity is completed because (abst 2 ) only allows us to introduce and make polymorphic some α with *.

This limits the expressiveness of λ2. Here, we can have variables x,y,... that are dependent on some α,β,.., but we can’t have some arbitrary type be dependent on another type.

Specifically, expressions of the sort :

i) λα : * . αα

ii) λα : * . λβ : * . αβ

are not possible in λ2.

Ideally, we would like these expressions to become placeholders for more generic types via β-reduction :

i) (λα : * . αα)γ β γγ

ii) (λα : * . αα)δ β δδ

iii) (λα : * . αα)(τ 1 τ 2 ) β (τ 1 τ 2 )(τ 1 τ 2 )

We can see that these allow us to substitute types into types. This is a very useful abstraction upon which many modern functional programming constructs rely. Monads, for example, often rely on implicitly Dependent-Types.

However, none of this machinery is possible in λ2, and we shall need new Semantics to introduce them : Enter λ ω .

SEMANTICS : Now that we know what shortcomings we had before, and what new expressive abilities we would like in our system (vaguely), let us begin to discuss the enhancements via new semantics.

First and foremost, let us analyze one of the previously mentioned lambda-terms that we would like in our new framework :

λα : * . αα

We would like this term can be a placeholder for any Type that is a binary operation of the arrow on itself. Therefore, we would like to type the term as :

λα : * . αα : ** In order to be able to generically type these "higher-order" Types, we need a new Super-Type to represent * and all * expressions over the binary operator . Terms from the said set are generally typed as :

So, all types like : *,**,(**)*,... have type :

Furthermore, to formalize this notion of abstract structure over these "higher-types", we introduce some simple terminology and grammar :

𝕂 = * | 𝕂𝕂

It is easy to see (by definition, in fact), that, κ𝕂, κ:.

These abstract "higher-types" are termed Kinds. They represent the Set of the new, more powerful Types that we want to type terms with and substitute into (in λ ω ).

The types : *, have a special name - sorts. They are represented as : sorts = {*,}. The symbol s refers to * or .

Terms such as the ones defined above, that take Types and construct new terms (of Types) from them, are called Type-Constructors.

Formally :

A Type-Constructor is a term MΛ ω , , M:κ.

If κ*, then it is referred to as a Proper Type-Constructor.

Now that we have an idea of what we want our Lambda-Terms in λ ω to look like, and what exactly our "Higher-Types" must look like, we can begin to introduce the Rules and Formal Semantics of our system.

The first thing we need to do is introduce the "Super-Type" in our Derivation rules so as to construct complex types. This is done via the (sort) rule :

(sort) ϕ *:

This rule is necessary for 2 reasons :

a) It allows us to introduce * and generically typed type-variables

b) It lays the foundations for the usage of the (form) rule (introduced ahead) on empty contexts (Γϕ)

Now that we can introduce the super-type () into our Lambda-Calculus, the next thing we want is the ability to introduce variables at 2 levels :

a) Those with type *

b) And variables that have a type of a type-variable

This is achieved via the (var) rule :

  1. ΓC : s

    Γ,x : Cx : C, if xΓ

As s represents a term from the set : {*,} we can see that 2 levels of terms can be introduced here. As an example, consider the following :

  1. ϕ* : ((sort))

    α : * α : * ((var) on (sort))

  2. α : * α : * (From (1.))

    α : *,x : αx : α )(var) on (1.))

However, with just (sort) and (var) we can’t generate all things that are present in the context (Γ). As an example, the following generations are not possible :

α : *,β : *β : *

α : *,β : *α : *

We need to solve this issue by effectively allowing for the weakening of Γ by allowing us to "re-derive" * : no matter what exactly Γ is. The rule that introduces this into the semantics of λ ω is (weak) :

  1. ΓA : B, ΓC : s

    Γ,x : CA : B if xΓ

Again, it’s easy to see that the Rule allows for "weakening" at the level of terms of types, and types of higher-kinds. This can be seen pretty easily in the following example :

  1. ϕ* : , ϕ* : ((sort)×2)

    α : ** : ((weak))

  2. ϕ* : ((sort))

    α : *α : * ((var))

  3. α : ** : (From (1.))

    α : *,β : *β : * ((var) on (1.))

  4. α : *α : *, α : ** : (From (1.) and (2.))

    α : *,β : *α : * ((weak))

So, we’ve gained the ability to fully express our Context (Γ) and introduce the super-type into our derivations. The only semantic we need before introducing (appl) and (abst) into our rules is that of the ability to construct any κ𝕂. This can be introduced by the simple (form) rule :

  1. ΓA : s, ΓB : s

    ΓAB : s

Once again, it is easy to see that this not only introduces the elements of 𝕂, but also allows us to type term-variables with type-variables.

We are now in a place to introduce the much awaited (appl) and (abst) rules for λ ω :

  1. ΓM : AB, ΓN : A

    ΓMN : B

  2. Γ,x : AM : B, ΓAB : s

    Γλx : A . M : AB

These rules are actually fairly intuitive, and once again, easy to verify as to being applicable for introducing and applying to term-variables and type-variables.

The last rule that we need to construct our Types-Depdent-On-Types λ ω is the (conv) rule :

  1. ΓA : B, ΓB ' : s

    ΓA : B ' , if B= β B '

The reason we need the (conv) rule is to formalize our intuition for circumstances where a variable can be typed with 2 β-equivalent types. Consider the following type-term :

(λα : * . α . αα)β β ββ

Supposing we have some Γ, where, x : (λα : * . α . αα)β and xΓ

Clearly, x : ββ as a type is equivalent to the one that x is typed with in the context Γ. This is the exact intuition that the (conv) rule formalizes. The (conv) rule allows this for all types up to β-equivalence.

One should be careful so as to not confuse the Subject-Reduction Lemma with the (conv) rule. The former states that two β-equivalent terms have the same type, while the latter states that a term can be typed with all β-equivalent types. If there is some confusion regarding the fact that β-reduction is applying over here to terms and types, then one can simply glance at the rules for λ ω to understand that, as types are more complicated in λ ω and can be applied to and abstracted on to create more types, type-variables can be manipulated in ways that they can’t in λ2. Hence, the concept of Dependent-Types.

Having derived all the Formal Semantics of λ ω we can now rewrite them collectively, and move on to the important Properties :

  1. ϕ *:

  2. ΓC : s

    Γ,x : Cx : C, if xΓ

  3. ΓA : B, ΓC : s

    Γ,x : CA : B, if xΓ

  4. ΓA : s, ΓB : s

    ΓAB : s

  5. ΓM : AB, ΓN : A

    ΓMN : B

  6. Γ,x : AM : B, ΓAB : s

    Γλx : A . M : AB

  7. ΓA : B, ΓB ' : s

    ΓA : B ' , if B= β B '

This is it. This is the λ ω .

As a last note - The λ ω does not contain -types. However, Girard’s extension of λ ω into what is called "System F ω " does.

PROPERTIES : This section is going to be succinct and I will mention the 3 most important properties about λ ω :

Theorem 1 : Uniqueness of Types - AΛ ω , if, (ΓA : B 1 )(ΓA : B 2 ), then, B 1 = β B 2 .

This Lemma is basically stating a formalism of the fact that a term can only be typed by two types if they are equivalent. The proof for this follows from Induction on the ways a term MΛ ω can be built, and using the (conv) rule for the Inductive Hypothesis.

Theorem 2 : Church-Rosser Theorem - M,N 1 ,N 2 Λ ω , (M β N 1 )(M β N 2 ), NΛ ω , M β N.

For a generic Proof of this Theorem, one may refer to the work by Henk Barendregt or that of Takahashi, 1995. The important part is that the theorem holds for the System λ ω .

Theorem 3 : Strong Normalization Theorem - MΛ ω , π=M β M 1 β M 2 ... β M n , where, M n is in β-nf.

This Theorem basically states that every term in λ ω is strongly-normalizing, or that evaluating leads to termination (and no form of undecidability or infinite looping). The Proof for this Theorem is highly non-trivial and uses the concept of Logical Relations to find a property that is an inductive invariant for the System.

At this point, we have covered a lot of ground and laid the foundations for λ ω by stating the motivating behind its construction, its semantics, and its three most crucial properties.

So, until the next post (where we will cover the Calculus-of-Constructions), the reader is encouraged to prove the 3 Properties!