The Polymorphic Blame Calculus and Parametricity Jeremy G. Siek Indiana University, Bloomington University of Strathclyde August 2015 1/ 31
Integrating static and dynamic typing Static Dynamic 2/ 31
Outline ◮ Quick review of gradual typing ◮ New: a polymorphic gradually typed lambda calculus ◮ Review: Poly. Blame Calculus and Parametricity 3/ 31
Gradual typing includes dynamic typing An untyped program: let f = λ y . 1 + y h = λ g . g 3 in h f − → 4 4/ 31
Gradual typing includes dynamic typing A buggy untyped program: 1 let 2 f = λ y . 1 + y 3 h = λ g . g true 4 in 5 h f − → blame ℓ 2 Just like dynamic typing, the error is caught at run time. 5/ 31
Gradual typing includes static typing A typed program: let f = λ y : int . 1 + y h = λ g : int → int . g 3 in h f − → 4 6/ 31
Gradual typing includes static typing An ill-typed program: 1 let f = λ y : int . 1 + y 2 3 h = λ g : int → int . g true 4 in 5 h f Just like static typing, the error is caught at compile time. Error on line 3, the argument true is a Boolean, but function g expects an int . 7/ 31
Gradual typing provides fine-grained mixing A partially typed program: let f = λ y : int . 1 + y h = λ g . g 3 in h f − → 4 8/ 31
Gradual typing protects type invariants A buggy, partially typed program: 1 let f = λ y : int . 1 + y 2 3 h = λ g . g true 4 in 5 h f − → blame ℓ 3 9/ 31
Gradually Typed Lambda Calculus Extends the STLC with a dynamic type, written ⋆ . Types A , B , C ::= ι | A → B | ⋆ Terms L , M , N ::= c | x | λ x : A . N | L M Consistency A ∼ B A 1 ∼ B 1 A 2 ∼ B 2 int ∼ int A ∼ ⋆ ⋆ ∼ B A 1 → A 2 ∼ B 1 → B 2 Term Typing Γ ⊢ M : A Γ ⊢ L : A → B C ∼ A Γ ⊢ L : ⋆ Γ ⊢ M : C Γ ⊢ M : C · · · Γ ⊢ L M : B Γ ⊢ L M : ⋆ 10/ 31
Outline ◮ Quick review of gradual typing ◮ New: a polymorphic gradually typed lambda calculus ◮ Review: Poly. Blame Calculus and Parametricity 11/ 31
Gradual typing and polymorphism Use polymorphic code in an untyped context: let pos = λ x . x > 0 app = Λ X . Λ Y . λ f : X → Y . λ x : X . f x in app pos 1 Use untyped code in a polymorphic context: let pos : int → bool = λ x : int . x > 0 app = λ f . λ x . f x in app int bool pos 1 12/ 31
Gradually Typed Polymorphic Lambda Calculus Types A , B , C ::= ι | A → B | ⋆ | X | ∀ X . A Terms L , M , N ::= c | x | λ x : A . N | L M | Λ X . N | L A Consistency A ∼ B Γ , X ⊢ A ∼ B X ∈ Γ · · · Γ ⊢ X ∼ X Γ ⊢ ∀ X . A ∼ ∀ X . B Γ , X ⊢ A ∼ B Γ , X ⊢ A ∼ B Γ ⊢ A ∼ ∀ X . B Γ ⊢ ∀ X . A ∼ B Term typing Γ ⊢ L : ∀ X . B Γ ⊢ L : ⋆ · · · Γ ⊢ L A : ⋆ Γ ⊢ L A : B [ X �→ A ] 13/ 31
Consistency examples ∀ X . X → X ∼ ∀ Y . Y → Y ∀ X . X → X ∼ ⋆ ⋆ ∼ ∀ X . X → X ∀ X . X → X ∼ ⋆ → ⋆ ⋆ → ⋆ ∼ ∀ X . X → X ∀ X . X → X �∼ int → int int → int �∼ ∀ X . X → X ∀ X . X → X �∼ int → bool int → bool �∼ ∀ X . X → X 14/ 31
What about converting poly. to simple? One might also want implicit conversion from polymorphic types to simple types, such as ∀ X . X → X ⇒ int → int That is a separate concern from gradual typing. We could handle it with a subtyping rule A [ X �→ C ] < : B ∀ X . A < : B Then, for the type checking algorithm, combine subtyping and consistency as in Siek and Taha [2007]. 1 2 1 Polymorphic type inference and containment, John C. Mitchell, Information and Computation 1988. 2 Gradual Type for Objects, Siek and Taha, ECOOP 2007. 15/ 31
Translation semantics (cast insertion) The semantics is defined by translation to the Polymorphic Blame Calculus. Γ ⊢ M � M ′ : A Cast Insertion Γ ⊢ L � L ′ : ⋆ · · · p Γ ⊢ L A � ( L ′ : ⋆ ⇒ ∀ X . ⋆ ) A : ⋆ 16/ 31
Outline ◮ Quick review of gradual typing ◮ New: a polymorphic gradually typed lambda calculus ◮ Review: Poly. Blame Calculus and Parametricity 17/ 31
Semantics of casting from poly. to untyped Recall the example: let pos = λ x . x > 0 app = Λ X . Λ Y . λ f : X → Y . λ x : X . f x in app pos 1 So we have the cast: p app : ∀ X . ∀ Y . ( X → Y ) → X → Y ⇒ ⋆ The Polymorphic Blame Calculus handles such casts by instantiating with ⋆ . p p V : ( ∀ X . A ) ⇒ B − → ( V ⋆ ) : A [ X �→ ⋆ ] ⇒ B 3 3 Blame for All. Ahmed et al. POPL 2011 18/ 31
Semantics of casting from untyped to poly. Recall the example: let pos : int → bool = λ x : int . x > 0 app = λ f . λ x . f x in app int bool pos 1 So we have the cast: p app : ⋆ ⇒ ∀ X . ∀ Y . ( X → Y ) → X → Y The Polymorphic Blame Calculus handles such casts by generalizing. p p V : A ⇒ ( ∀ X . B ) − → Λ X . ( V : A ⇒ B ) if X / ∈ ftv ( A ) 19/ 31
Semantics of casts and parametricity Consider casting the constant function K = λ x : ⋆ . λ y : ⋆ . x to the following polymorphic types p K 1 ≡ K : ⋆ → ⋆ → ⋆ ⇒ ∀ X . ∀ Y . X → Y → X q K 2 ≡ K : ⋆ → ⋆ → ⋆ ⇒ ∀ X . ∀ Y . X → Y → Y and the following scenarios: → ∗ 1 ( K 1 int bool ) 1 false − ( K 2 int bool ) 1 false − → ∗ → ∗ 1 ( K 1 int int ) 1 2 − ( K 2 int int ) 1 2 − → ∗ 20/ 31
Instantiation as type substition Recall the traditional reduction rule: (Λ X . N ) A − → N [ X �→ A ] q K 2 ≡ K : ⋆ → ⋆ → ⋆ ⇒ ∀ X . ∀ Y . X → Y → Y ( K 2 int bool ) 1 false p − → ∗ ( K : ⋆ → ⋆ → ⋆ ⇒ int → bool → bool ) 1 false p − → ∗ 1 : int ⇒ ⋆ ⇒ bool → blame p − so far so good... 21/ 31
The problem with type substitution q K 2 ≡ K : ⋆ → ⋆ → ⋆ ⇒ ∀ X . ∀ Y . X → Y → Y The second scenario for K 2 : ( K 2 int int ) 1 2 p → ∗ ( K : ⋆ → ⋆ → ⋆ ⇒ int → int → int ) 1 2 − p → ∗ 1 : int ⇒ ⋆ − ⇒ int − → 1 but a polymorphic function of type ∀ X . ∀ Y . X → Y → Y must return its second argument, not first! 22/ 31
Solution: don’t substitute, seal (Λ X . V ) A − → ν X �→ A . V The example revisited: q K 2 ≡ K : ⋆ → ⋆ → ⋆ ⇒ ∀ X . ∀ Y . X → Y → Y ( K 2 int int ) 1 2 → ∗ ( ν X �→ int . ν Y �→ int . K : ⋆ → ⋆ → ⋆ p − ⇒ X → Y → Y ) 1 2 → ∗ ν X �→ int . ν Y �→ int . 1 : X ⇒ ⋆ p − ⇒ Y → blame p − 4 4 Types are not sets, James H. Morris, Jr., POPL 1973. 23/ 31
What to do with escaping seals? p (Λ X . λ x : X . x : X ⇒ ⋆ ) int 2 p → ∗ ν X �→ int . 2 : X − ⇒ ⋆ → blame p ν − Contrast with (Λ X . λ x : X . inl x as ( X + bool )) int 2 → ∗ inl 2 as ( int + bool ) − Why not? p p ν X �→ A . ( V : X ⇒ ⋆ ) − → ( ν X �→ A . V ) : A ⇒ ⋆ 24/ 31
Properties of the Polymorphic Blame Calculus � Type Safety � Blame Theorem � Subtyping Theorem (weak version) � Subtyping Theorem (strong version) � Parametricity 25/ 31
Blame Theorem Theorem (Blame Theorem) p Let M be a program with a subterm N : A ⇒ B where the cast is labelled by the only occurrence of p in M, and p does not appear in M. ◮ If A < : + B, then M �− → ∗ blame p. ◮ If A < : − B, then M �− → ∗ blame p. → ∗ blame p. ◮ If A < : n B, then M �− → ∗ blame p. ◮ If B < : n A, then M �− 26/ 31
Subtyping Theorem Theorem (Subtyping Theorem) p Let M be a program with a subterm N : A ⇒ B where the cast is labelled by the only occurrence of p in M, and p does not appear in M. → ∗ blame p and M �− → ∗ blame p. ◮ If A < : B, then M �− Weak version: A [ X �→ ⋆ ] < : B ( ∀ X . A ) < : B (Proved in STOP 2009.) Strong version: A [ X �→ T ] < : B ( ∀ X . A ) < : B (Incorrect proof in POPL 2011.) 27/ 31
Jack of all trades Conjecture (Jack-of-All-Trades) If ∆ ⊢ V : ∀ X . A and A [ X �→ C ] ≺ B (and hence A [ X �→ ⋆ ] ≺ B) then p p ( V C : A [ X �→ C ] ⇒ B ) ⊑ ( V ⋆ : A [ X �→ ⋆ ] ⇒ B ) . 28/ 31
Speculating about parametricity Logical Relation Terms E [ A ] δ k = { ( M , N ) | ∃ VW . M ⇓ j V , N ⇓ j W , ( V , W ) ∈ V [ A ] δ ( k − j ) } Values V [ int ] δ k = { ( n , n ) | n ∈ Z } V [ A 1 + A 2 ] δ k = { ( inj i V , inj i W ) | i ∈ 1 .. 2 , ( V , W ) ∈ V [ A i ] δ k } · · · V [ ∀ X . A ] δ k = { ( V 1 , V 2 ) | ∀ R . ( V 1 [ · ] , V 2 [ · ]) ∈ E [ A ] δ ( X �→ R ) k } V [ X ] δ k = δ ( X ) k V [ ⋆ ] δ ( 1 + k ) = { ( V : G ⇒ ⋆, W : G ⇒ ⋆ ) | ( V , W ) ∈ V [ G ] δ k } 29/ 31
Parametricity Conjecture (Soundness of the Logical Relation) If ∆; Γ ⊢ M ≈ N : A, then ∆; Γ ⊢ M = ctx N : A. Conjecture (Fund. Theorem of Logical Relations) If ∆; Γ ⊢ M : A, then ∆; Γ ⊢ M ≈ M : A. 30/ 31
31/ 31
Recommend
More recommend