types and programming languages - sjtuxiaojuan/tapl2016/files/lec10_handout.pdfi polymorphism means...

Post on 24-Aug-2020

4 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Types and Programming Languages

Lecture 10. Universal and existential types

Xiaojuan Cai

cxj@sjtu.edu.cn

BASICS Lab, Shanghai Jiao Tong University

Fall, 2016

Coming soon

I We studied the simple form of let-polymorphism found in ML.

I We will consider a more general form of polymorphism:universal types in the setting of System F.

I We will find existential types very useful for data abstractionin programming languages.

I We also will study (very briefly) bounded quantifications whichare the mixture of universal (existential) types and subtyping.

Outline

Universal types

Existential typesData abstraction

Bounded quantification

Motivation

Can we write an infinite number of ”doubling” functions?

doubleNat=λf:Nat→Nat.λx:Nat.f(f x);

doubleRcd=λf:{l:Bool}→{l:Bool}.λx:{l:Bool}.f (f x);

doubleFun=λf:(Nat→Nat)→(Nat→Nat).λx:Nat→Nat.f(fx);

Abstraction principle. Where similar functions are carried out bydistinct pieces of code, it is generally beneficial to combine theminto one by abstracting out the varying parts.

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 isalways subtyping polymorphism, and they call parametricpolymorphism 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

Examples

We will see several examples to illustrate the expressive power ofSystem F.

I A polymorphic identity function:id = λX.λx : X.xid[Nat] 0

I A self-application, λx .xx :selfApp = λx : ∀X.X→ X. x[∀X.X→ X] x

Quiz.

I Give the definition of polymorphic doubling function.doubleNat=λf:Nat→Nat.λx:Nat.f(f x);

double = λX.λf:X→X.λx:X.f(f x)

I Try to type (λx .xx)(λx .xx) in System F.We can not type (λx .xx)(λx .xx) in System F.

Church encodings

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.

Church booleans

I In untyped λ-calculus

tru = λt.λf .tfls = λt.λf .f

I In System F

CBool = ∀X .X → X → Xtru = λX .λt : X .λf : X .tfls = λX .λt : X .λf : X .f

Church pairs

I In untyped λ-calculus

pair = λf .λs.λb.b f sfst = λp.p tru

snd = λp.p fls

I In System F

Pair X Y = ∀R.(X → Y → R)→ Rpair = λX .λY .λf : X .λs : Y .λR.λb : (X → Y → R).b f s

fst = λX .λY .λp : Pair X Y .p[X ] (λf : X .λs : Y .f )snd = λX .λY .λp : Pair X Y .p[Y ] (λf : X .λs : Y .s)

Church numerals

I In untyped λ-calculus

0 = λs.λz .z1 = λs.λz .s z2 = λs.λz .s (s z)3 = λs.λz .s (s (s z))· · ·

I In System F

CNat = ∀X .(X → X )→ X → X0 = λX .λs : X → X .λz : X .z1 = λX .λs : X → X .λz : X .s z2 = λX .λs : X → X .λz : X .s (s z)

csucc = λn : CNat.λX .λs : X → X .λz : X .n[X ] s (s z)

List

I In untyped λ-calculus

list[x , y , z ] = λc .λn.c x (c y (c z n))nil = λc .λn.n

cons = λh.λt.λc .λn.c h (t c n)isnil = λl .l (λh.λt.fls) tru

I In System F

List X = ∀R.(X → R → R)→ R → Rnil = λX .λR.λc : X → R → R.λn : R.n

cons = λX .λh : X .λt : (List X ).λR.λc : X → R → R.λn : R.c h (t[R] c n)

isnil = λX .λl : (List X ).l [CBool ] (λh : X .λt : CBool .fls) tru

Properties of universal types

Theorem 23.5.1 [Preservation]: If Γ ` t : T and t −→ t, thenΓ ` t ′ : T.

Theorem 23.5.2 [Progress]: Suppose t is a closed, well-typedterm. Then either t is a value or else there is some t with t −→ t.

Theorem 23.5.3 [Normalization]: Well-typed System F termsare normalizing.

Erasure

erase(x) = xerase(λx : T1.t2) = λx .erase(t2)erase(t1 t2) = erase(t1) erase(t2)erase(λX .t2) = erase(t2)erase(t1[T2]) = erase(t1)

Type reconstruction problem. A term m in the untypedlambda-calculus is said to be typable in System F if there is somewell-typed term t such that erase(t) = m.

Theorem [Undecidability, Wells 1994]. Type reconstruction forSystem F is undecidable.

Fragments of System F

The lack of type reconstruction leads to various fragments ofsystem F with type reconstruction.

I let-polymorphism in SML

I rank-2 polymorphism, no path from root to the quantifierpasses to the left of 2 or more arrows, e.g.,(∀X.X→ X)→ Nat, but ((∀X.X→ X)→ Nat)→ Nat is notrank-2.

Universal types

Existential typesData abstraction

Bounded quantification

Motivation

I Since there are universal quantifiers in type systems, it isnatural to wonder whether existential quantifiers might alsobe useful in programming.

I The answer is “yes” and existential types offer an elegantfoundation for data abstraction.

Existential type

I We use {∃X ,T} to denote existential type.

I An element of existential type is a pair, written {∗S , t} whereS 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 The elements of a existential type are called packages.

Typing rules

I intro-rule:

T-PackΓ ` t2 : [X 7→ U]T2

Γ ` {∗U, t2} as {∃X ,T2} : {∃X ,T2}

I elimin-rule:

T-UnPackΓ ` t : {∃X .T}, Γ,X , x : T ` t2 : T2

Γ ` let {X , x} = t in t2 : T2

Evaluation rules

I computation-rule:

let {X , x} = ({∗T1, v1} as T ) in t2 −→ [X 7→ T1][x 7→ v1]t2

I congruence rules:

t1 −→ t ′1{∗T1, t1} as T −→ {∗T1, t

′1} as T

t1 −→ t ′1

let {X , x} = ({∗T1, t1} as T ) in t2−→ let {X , x} = ({∗T1, t

′1} as T ) in t2

Examples

Quiz. Please draw the type derivation tree of the following terms:

1. p4={*Nat, {a=0, f=λx:Nat.succ(x)}} as {∃X, {a:X,f:X→Nat}};

2. p5={*Bool, {a=true, f=λx:Bool.0}} as {∃X, {a:X,f:X→Nat}};

3. up1 = let {X,x}=p4 in (x.f x.a);

4. up2 = let {X,x}=p4 in succ(x.a);

Outline

Universal types

Existential typesData abstraction

Bounded quantification

Existential types and data abstraction

I We have seen that type systems can catch small-scaleprogramming errors like 2+true.

I Type systems also offer crucial support for programming inthe large.

I We will see the usage of existential types for abstraction.

Abstract Data Type, ADT

ADT counter =

type Counter

representation Nat

signature

new : Counter,

get : Counter→Nat,

inc : Counter→Counter;

operations

new = 1,

get = λi:Nat.i,inc = λi:Nat.succ(i);

counter.get (counter.inc counter.new);

ADT as existential type

counterADT =

{*Nat,new = 1,

get = λi:Nat.i,inc = λi:Nat.succ(i)}

as {∃Counter,{new: Counter,

get: Counter→Nat,

inc: Counter→Counter}};

ADT hiding implementations

counterADT =

{*{x:Nat},new = {x=1},get = λi:{x:Nat}.x.i,inc = λi:{x:Nat}.{x=succ(x.i)}}

as {∃Counter,{new: Counter,

get: Counter→Nat,

inc: Counter→Counter}};

Outline

Universal types

Existential typesData abstraction

Bounded quantification

Motivation

I Polymorphism + Subtyping?

I We can keep them orthogonal.

I However, it will be more interesting if we mix them in someways.

Coming soon.

I A simple illustrating example

I F<:

An illustrating example

I An identity function on records:f = λx:{a:Nat}.xra = {a = 0}rab = {a = 0, b = 0}

I With T-Sub, we can apply f to both ra and rab.

I However, the term (f rab).b will be ill-typed.

I What about a polymorphic f?f = λX.λx:X.x

I It also can be applied to both ra and rab. And (f rab).b iswell-typed.

An illustrating example, cont’d

I Neither works if we want to define f asf = λx :?.{orig=x, geta = x.a}

I Polymorphism + Subtyping = bounded quantification

I A solution to above example might be:f = λX<:{a:Nat}.λx:X.{orig=x, geta = x.a}

I Please refer to Figure 26-1 for full definition of F<:

About F<:

I Bounded and Unbounded Quantification

∀X .T = ∀X <: Top.T

I Quiz. Draw the type derivation tree for f rab.

I Type safety property holds for F<:.

Conclusion

I Polymorphism means a single piece of code to be used withmultiple types.

I We have parametric polymorphism (this lecture), ad-hocpolymorphism (overloading) and subtyping polymorphism(OO).

I System F = simply typed λ-calculus + type abstraction andapplication (universal types).

I Universal types are crucial for polymorphism.

I Existential types are crucial for data abstraction.

I Polymorphism + subtyping = bounded quantification (F<:).

Homework

I 23.4.1, 23.4.3 (offline part), 23.4.4, 23.4.6, 23.4.12, 24.2.2,

top related