What needs to have a type?

We will define a type T->T where the first T is the domain and the second T is the range. The -> acts as a type constructor.

T1->T2 says if given a type T1 a function will return a type T2

T ::= T->T

The problem with this is that there are no base cases. So we need base types. Base types are concrete types.

Here we add Bool

T ::= T->T | Bool

We can now type a lambda as following:

(λx: Bool.x): Bool→Bool

It can also be applied for App:

(((λx: Bool.x): Bool→Bool) true): Bool

Type Ascription

In general it is impossible to figure out a λ's input type from its output type. Function application "removes" information.

Type Rules

t1:T1→T2t2:T1(t1 t2): T2TApp
Note

The context of a term is a list of all the bound variables and their types.

A type rule for variables is as follows

(x→T)∈ΓΓ⊢x:TTVar

Syntax

t ::=λx:T.t | (t t) | x
v ::=λx:T.t
T ::=T→T

Type Safety

Proof of Progress

if Γ⊢t:T then t is a value or t→t′, ∃t′

Proof.

Proof of Preservation

This involves the use of a few other lemmas.

Permutation Lemma

If Γ⊢t:t and Δ is a permutation of Γ, then delta⊢t:T.

This says that the ordering of Γ doesn't matter. This is not always true.

In order to prevent this we prevent shadowing meaning a variable can't be used more than once. Languages like Haskell get around this by mangling variables and renaming them to be unique, this is called alpha reduction.

Proof.

By induction on terms:

Γ⊢x:T implies (x→T)∈Γ by type inversion. By definition of permutation (x→T)∈Δ so Δ⊢x:T by TVar.

Γ⊢(λx:T1.t2):T1→T2 by type inversion. The induction hypothesis says permutation holds for (x→T1), Δ⊢t2:T2. Thus Δ⊢(λx:T1.t2):T1→T2 holds by TLambda

Γ⊢(t1 t2):T2 implies there exists some Γ⊢t1:T1→T2 and Γ⊢t2:T1 by type inversion. Induction hypothesis says permutation holds Δ⊢t1:T1→T2. Thus Δ⊢(t1 t2):T2 holds by TApp.

Weakening Lemma

If Γ⊢t:T and x∉dom(T) then (x→S),Γ⊢t:T

This essentially says typing is invariant if unique variables are added to the context.

Preservation of Types Under Substitution

If (x→S),Γ⊢t:T and Γ⊢s:S then Γ⊢...

This essentially says typing is invariant with respect to replacing a well-typed variable with a well-typed term of the same type.

Proof.

The Proof

uhhh...

Simple Extensions

There are three ways to enrich a language:

  1. Extension - Add new syntax, new values, new types and associated inference rules
  2. Derived Forms - Add new syntax and new types defined in terms of existing constructs
  3. Libraries - Add new functionality by using the language to define new resuable constructs

Prefer 2 over 3

Base Types

Extend the definition of T to include arbitrary uninterpretable base types.

T::= ...| A | T→T


Unit and ;

Unit is a type with a single value.

Syntax:

t::=...| unit
v::=...| unit
T::=...| Unit

Type Rules:

Γ⊢unit:Unit

Conservative Extensions

A conservative extension is an extension to a language that does not reference any other bits of the language. It does not affect how the language works.

Unit in this case is a conservative extension.

Derived Form:

t1;t2≡(λx:Unit.t2)t1,where x∉FV(t2)

Note

This assumes call by value evaluation semantics.

This is defining sequencing (;) such that t1 is evaluated before t2. The where condition also requires that x doesn't appear in t2 so that it does not affect the evaluation of t_2.

Derived forms are evaluated by expanding the syntax with their definition

Inference Rules:

t1→t1′t1;t2→t1′;t2ESeqFirst

The above rule requires t1 to be evaluated first.

unit;t2→t2ESeqUnit

This rule takes the unit production of the first rule and removes it to evaluate t2

Type Rules:

Γ⊢t2:UnitΓ⊢t2:TΓ⊢t1;t2:T

Let Binding

Syntax

t::= ...| let x=t in t

Evaluation Rules

let x=t in t2→[x→v1]t2let x=t1 in t2→let x=t1′ in t2

Type Rules

Γ⊢t1 : T1(x→T1),Γ⊢t2 : T2Γ⊢let x=t1 in t2 : T2

Derived Forms

let x=t1 in t2 ≡ ((λx:T.t1) t2)

Some Proofs

Define e

e x≡x
e (λx.t)≡λx.e t
e (t1 t2)≡((e t1) (e t2))
e let x=t1 in t2

Pairs

Syntax

t::= ...| {t,t} | t.1 | t.2
v:: ...| v,v
T::= ...| T1\crossT2

Evaluation Rules

{v1,v2}.1→v1EProj1{v1,v2}.2→v2EProj2t→t′t.1→t′.1EPair2t→t′t.2→t′.2EPair2t1→t1′{t1,t2}→{t1′,t2}t2→t2′{v1,t2}→{v1,t2′}

Type Rules

Γ⊢t1:T1Γ⊢t1:T2Γ⊢{t1,t2}:T2×T2TPairΓ⊢t:T1×T2Γ⊢t.1:T1TProj1Γ⊢t:T1×T2Γ⊢t.2:T2TProj2

Sums and Products

Recursion and letrec