types and programming languages reviewsxiaojuan/tapl2016/files/lec... · 2016-12-04 · i subtyping...
TRANSCRIPT
Types and Programming Languages
Reviews
Xiaojuan Cai
BASICS Lab, Shanghai Jiao Tong University
Fall, 2016
Course Overview, I
I Structural induction
I Untyped systems: arithmetic expression, λ-calculus, De Bruijnnotation for terms
I Typed systems: safety = preservation + progress, functiontypes, Simply typed λ-calculus
I Simple extensions: base, unit, ascription, let-binding, pairs,tuples, records, sums, variants, general recursion,normalization
I More extensions: references and exceptions
Course Overview, II
I Subtyping: properties, metatheory
I Recursive types: two views, coinduction and subtypingmembership checking
I Type reconstruction: type variables, unification,let-polymorphism
I Universal and existential types: polymorphisim, System F,data abstraction, bounded quantification
Type system
Our course focuses on static type system, and types are good for:
I Detecting errors early.
I Maintenance tools.
I Abstracting
I Documentation
I Language safety. A safe language is one that protects its ownabstractions. C/C++ are unsafe.
I Efficiency
I Applications: network security, program analysis, theoremprover, database, xml, ...
I Language design goes hand-in-hand with type system design.
Induction on terms
I Induction on depth:If, for each term s,
given P(r) for all r such that depth(r) < depth(s),we can show P(s),
then P(s) holds for all s.
I Induction on size:If, for each term s,
given P(r) for all r such that size(r) < size(s),we can show P(s),
then P(s) holds for all s.
I Structural Induction:If, for each term s,
given P(r) for all immediate subterms r of s,we can show P(s),
then P(s) holds for all s.
Untyped λ-calculus: Syntax and semantics
Syntax.
t ::= termsx variableλx .t abstractiont t application
Semantics.
β-reduction(λx .s) t −→ [x 7→ t]s
I Full β-reduction: any redex may be reduced at any time.
I Call by name: leftmost, outermost redex is reduced first, andno redex inside abstractions is allowed to reduce.
I Call by value: outermost redexes are reduced and only itsargument part has already been reduced to a value.
We use call-by-value in this course.
APP1t1 −→ t ′1
t1 t2 −→ t ′1 t2
APP2t2 −→ t ′2
v1 t2 −→ v1 t′2
APPABS(λx .t) v −→ [x 7→ v ] t
I λ-calculus is Turing complete.
I It can encode booleans, pairs, numerals and recursivefunctions.
Types
I If a term is well typed, i.e., it has some type T , then it neverget stuck (never goes wrong).
I The most basic property of type system: safety = progress +preservation
I Progress: A well-typed term is not stuck (either it is a value orit can take a step according to the evaluation rules).
I Preservation: If a well-typed term takes a step of evaluation,then the resulting term is also well typed.
I The proofs are always by induction on the derivation ofΓ ` t : T .
Pure simply typed λ-calculus (λ→)
Terms t ::= x | λx : T .t | t t
Values v ::= λx : T .t
Types T ::= T→ T
Contexts Γ ::= ∅ | Γ, x : T
Typing
T-Varx : T ∈ ΓΓ ` x : T
T-AbsΓ, x : T1 ` t2 : T2
Γ ` λx : T1 .t2 : T1 → T2
T-AppΓ ` t1 : T1 → T2 Γ ` t2 : T1
Γ ` t1 t2 : T2
Simple extensions
I Base type: A
I Unit: unit : UnitI sequencing: t1; t2: new syntax v.s. derived form
I new syntax: add operational semantic rules
I derived form: t1;t2def= (λx : Unit .t2) t1 where x 6∈ FV (t2)
I Ascription: t as Tdef= (λx : T.x)t
I let bindings: let x = t1 in t2I We do not treat let binding as derived forms.
I Pairs and tuples: {t i∈1..ni } | t.i , type {T i∈1..ni }
I Records: {li = t i∈1..ni } | t.li , type {li : T i∈1..ni }
I Variants: < l = t > as T, case t of < li = xi >⇒ ti∈1..ni ,type < li : Ti∈1..ni >
I General recursion: fix. λ→ + Nat + fix = PCF
Normalization
I The evaluation of a well-typed program in pure simply typedλ-calculus is guaranteed to halt in a finite number of steps.
I Holds for λ→ and System F.
Impure feature: references
I In nearly every PL, we have variable whose value is a reference(or pointer) to a mutable cell.
I allocation: r = ref 5;
I dereferencing: !r;
I assignment: r := 7;
I References (alias) make program hard to reason about.
Exceptions
Three settings:I an exception is a whole-program abort:
I error is not a value, error has any type T.
I trapping and recovering from exceptions:I try t with t
I extra programmer-specified data being passed betweenexception sites and handlers:
I try (raise v1) with t2 −→ t2 v1
Course Overview, II
I Subtyping: properties, metatheory
I Recursive types: two views, coinduction and subtypingmembership checking
I Type reconstruction: type variables, unification,let-polymorphism
I Universal and existential types: polymorphisim, System F,data abstraction, bounded quantification
SubtypingPrinciple of safe substitution. If S <: T, then any term of type S
can safely be used in a context where a term of type T is expected.
T-SubΓ ` t : S S <: T
Γ ` t : T
Subtyping rules:
S-ReflS <: S
S-TranS <: T T <: U
S <: U
S-Rcd{li∈1..ni } ⊆ {kj∈1..mj } and kj = li implies Sj <: Ti
{kj : Sj∈1..mj } <: {li : Ti∈1..ni }
S-ArrowT1 <: S1 S2 <: T2S1 → S2 <: T1 → T2
S-RefS1 <: T1 T1 <: S1Ref S1 <: Ref T1
Metatheory of subtypingI Subtype relation is not immediately suitable for
implementation. It is not syntax directed.I Subtype cannot just be ”read from bottom to top” to yield a
typechecker.
Algorithmic subtyping
SA-Top|= S <: Top
SA-Arrow|= T1 <: S1 |= S2 <: T2
|= S1 → S2 <: T1 <: T2
SA-Rcd{li∈1..ni } ⊆ {kj∈1..mj } and kj = li implies |= Sj <: Ti
|= {kj : Sj∈1..mj } <: {li : Ti∈1..ni }
Algorithmic typing
TA-AppΓ |= t1 : T1 → T2 Γ |= t2 : S1 |= S1 <: T1
Γ ` t1 t2 : T2
Recursive type
A general mechanism to define recursive data structures: recursivetypes.
T ::= ... | X | µX.T
Recursive types are powerful:
I It can represent infinite data, e.g. streams:upfrom0 = fix (λf:Nat->Stream.λn:Nat.λ :Unit.{n,f(succ n)}) 0
I It makes fix typable. (Remember we add fix explicitly inPCF.)
I It even makes untyped λ-calculus typable.
Two formalities for recursive types
I The equi-recursive approach takes these two expressionsdefinitionally equal – interchangeable in any context.
I Pros:I More intuitive;I Match with all the previous presentations. Definitions, safety
theorems and even proofs remains unchanged.
I Cons:I The implementation requires some work, Since type checking
can not work directly with infinite structures.
I The iso-recursive approach takes these two expressiondifferent, but isomorphic.
I Pros:I Less work for type systems.I Easy to interact with other features.
I Cons:I Heavier: requiring programs to be decorated with fold and
unfold.
Subtyping in two formalitiesI Assume Even is a subtype of Nat. What the relation between
these two types?
µX.Nat→ (Even× X) and µX.Even→ (Nat× X)
Induction and coinductionDefinition. A function F ∈ P(U)→ P(U) is monotone if X ⊆ Yimplies F (X ) ⊆ F (Y ), where P(U) is the powerset of U .
Definition. Let X be a subset of U .
I X is F -closed if F (X ) ⊆ X .
I X is F -consistent if X ⊆ F (X ).
I X is a fixed point if X = F (X ).
Theorem [Knaster-Tarski].
I The intersection of all F -closed sets is the least fixed point ofF , denoted µF ;
I The union of all F -consistent sets is the greatest fixed pointof F , denoted νF .
Corollary.
I Principle of induction: If X is F -closed, then µF ⊆ X ;
I Principle of coinduction: If X is F -consistent, then X ⊆ νF ;
Subtyping for finite and infinite tree types
Definition 21.3.1. Two finite tree types S and T are in thesubtype relation if (S ,T ) ∈ µSf , where the monotone functionSf ∈ P(Tf × Tf )→ P(Tf × Tf ) is defined by
Sf (R) = {(T , Top) | T ∈ Tf }∪ {(S1 × S2,T1 × T2) | (S1,T1), (S2,T2) ∈ R}∪ {(S1 → S2,T1 → T2) | (T1,S1), (S2,T2) ∈ R}.
Definition 21.3.2. Two tree types S and T are in the subtyperelation if (S ,T ) ∈ νS , where the monotone functionS ∈ P(T × T )→ P(T × T ) is defined by
S(R) = {(T , Top) | T ∈ T }∪ {(S1 × S2,T1 × T2) | (S1,T1), (S2,T2) ∈ R}∪ {(S1 → S2,T1 → T2) | (T1, S1), (S2,T2) ∈ R}.
Type reconstruction
Can we reconstruct all the type info when programmers leave outall type annotations?
Constraint + unification algorithm
Constraints are generated as type checking.
Unification
Theorem. The algorithm unify always terminates, failing whengiven a nonunifiable constraint set as input and otherwise returninga principal unifier.
let polymorphismfun double f = fn x => f (f x)
val x = (f 1, f true)
With type reconstruction algorithms discussed above, this programis not well-typed.ML-family solve this problem via let-polymorphism.
val x = let fun double = fn f => fn x => f (f x)
in (f 1, f true)
end
Old rule:
T-LetΓ ` t1 : T1, Γ, x : T1 ` t2 : T2
let x = t1 in t2 : T2
New rule:
CT-LetPolyΓ ` [x 7→ t1]t2 : T2
let x = t1 in t2 : T2
Polymorphism
Polymorphism: a single piece of code to be used with multipletypes.
I Parametric polymorphism. Using variables in place of actualtypes, and then instantiated with particular types as needed.
I Ad-hoc polymorphism. Allowing a polymorphic value toexhibit different behaviors when “viewed” at different types,e.g., overloading
I Subtyping polymorphism. Giving a single term many typesusing the rule of subsumption.
For functional programmers, polymorphism is always parametricpolymorphism.However, for OO programmers, polymorphism is always subtypingpolymorphism, and they call parametric polymorphism genericity.
System F [Girard 1972, Reynold 1974]System F = Polymorphic λ-calculus = second-order λ-calculusSystem F is a simply typed λ-calculus with type abstractions andtype applications (instantiations).
t ::= ... | λX .t | t[T ]
v ::= ... | λX .t
T ::= ... | ∀X .T
Γ ::= ... | Γ,X
E-TAppt1 −→ t ′1
t1[T2] −→ t ′1[T2]E-Tabs
(λX .t1)[T2] −→ [X 7→ T2]t1
T-TabsΓ,X ` t1 : T1
Γ ` λX .t1 : ∀X .T1T-Tapp
Γ ` t1 : ∀X .T1
Γ ` t1[T2] : [X 7→ T2]T1
System F
I System F is more expressive than λ→.
I Church encodings can be carried out in System F.
I We can add booleans, nats, ... as primitives.
I System F is not Turing powerful (The well-typed terms arenormalizing).
I However, in practice we use fragments of system F with typereconstruction. (let-polymorphism, or rank-2 polymorphism)
Theorem [Wells 1994]. Type reconstruction for System F isundecidable.
Existential types and data abstraction
I An element of existential type {∃X ,T} is a pair, written{∗S , t} where S is a type and t has type [X 7→ S ]T .
I For example, {∗Nat, {a = 5, f = λx : Nat.succ(x)}} has type{∃X , {a : X , f : X → X}}, and it also has type{∃X , {a : X , f : X → Nat}}.
I User has to add annotations to tell the type checker about theexistential type by using ascription.
I Existential type can be encoded by universal type.
T-UnPackΓ ` t : {∃X .T}, Γ,X , x : T ` t2 : T2
Γ ` let {X , x} = t in t2 : T2
let {X , x} = ({∗T1, v1} as T ) in t2 −→ [X 7→ T1][x 7→ v1]t2
Bounded quantification
I Polymorphism + Subtyping = bounded quantification
I System F<:
I f = λX<:{a:Nat}.λx:X.{orig=x, geta = x.a}
Course Overview, I
I Structural induction
I Untyped systems: arithmetic expression, λ-calculus, De Bruijnnotation for terms
I Typed systems: safety = preservation + progress, functiontypes, Simply typed λ-calculus
I Simple extensions: base, unit, ascription, let-binding, pairs,tuples, records, sums, variants, general recursion,normalization
I More extensions: references and exceptions
Course Overview, II
I Subtyping: properties, metatheory
I Recursive types: two views, coinduction and subtypingmembership checking
I Type reconstruction: type variables, unification,let-polymorphism
I Universal and existential types: polymorphisim, System F,data abstraction, bounded quantification
Office hours
I Dec 5 - Dec 8, 14:00 - 16:00, Software Building 3203
The End
“Begin at the beginning” the King said, very gravely,“and go on till you come to the end: then stop.”
— Lewis Carroll