Well-typed programs can’t be blamed Philip Wadler University of Edinburgh NII Shonan Meeting 26–30 May 2014
Publications • Wadler and Findler Well-typed programs can’t be blamed ESOP 2009 • Siek and Wadler Threesomes, with and without blame POPL 2010 • Ahmed, Findler, Siek, and Wadler Blame for all POPL 2011 • Siek, Thiemann, Wadler Blame, coercions, and threesomes, precisely draft
A repeated theme Henglein (1994): Coercions Findler and Felleisen (2002): Contracts Flanagan (2006): Hybrid types Siek and Taha (2006): Gradual types
A repeated theme Dynamic in .Net C#, Visual Basic JavaScript TypeScript Dart Perl 6.0 Python Reticulated Python
Part I From untyped to typed
An untyped program ⌈ let x = 2 f = λy. y + 1 h = λg. g ( g x ) in h f ⌉ − → ⌈ 4 ⌉
A typed program let x = 2 f = λy : Int . y + 1 h = λg : Int → Int . g ( g x ) in h f − → 4 : Int
A partly typed program—narrowing let x = 2 p f = ⌈ λy. y + 1 ⌉ : ⋆ ⇒ Int → Int h = λg : Int → Int . g ( g x ) in h f − → 4 : Int
A partly typed program—narrowing let x = 2 p f = ⌈ λy. false ⌉ : ⋆ ⇒ Int → Int h = λg : Int → Int . g ( g x ) in h f − → blame p Positive (covariant): blame the term contained in the cast
Another partly typed program—widening let x = ⌈ 2 ⌉ p f = ( λy : Int . y + 1 ) : Int → Int ⇒ ⋆ h = ⌈ λg. g ( g x ) ⌉ in ⌈ h f ⌉ − → ⌈ 4 ⌉
Another partly typed program—widening let x = ⌈ true ⌉ p f = ( λy : Int . y + 1 ) : Int → Int ⇒ ⋆ h = ⌈ λg. g ( g x ) ⌉ in ⌈ h f ⌉ − → blame ¯ p Negative (contravariant): blame the context containg the cast
Part II Untyped and supertyped
Untyped = Uni-typed ⌈ x ⌉ = x p ⌈ k ⌉ = k : A ⇒ ⋆ if ty ( k ) = A p � p ⌈ op ( � op ( ⌈ � ⇒ � if ty ( op ) = � M ⌉ : � M ) ⌉ = ⋆ A ) : B ⇒ ⋆ A → B ⌈ λx. N ⌉ = ( λx : ⋆. ⌈ N ⌉ ) : ⋆ → ⋆ ⇒ ⋆ p ⌈ L M ⌉ = ( ⌈ L ⌉ : ⋆ ⇒ ⋆ → ⋆ ) ⌈ M ⌉ (slogan due to Dana Scott, repeated by Bob Harper)
Contracts Nat = { x : Int | x ≥ 0 } let p x = 2 : Int ⇒ Nat q f = ( λy : Int . y + 1 ) : Int → Int ⇒ Nat → Nat h = λg : Nat → Nat . g ( g x ) in h f − → 4 : Nat
Part III The Blame Calculus
Notation It took us four years to find the right notation! � A ⇒ B � p s � B ⇐ A � p s p s : A ⇒ B We want composition to be easy to read: � B ⇒ C � q � A ⇒ B � p s � C ⇐ B � q � B ⇐ A � p s p q s : A ⇒ B : B ⇒ C And there is a convenient abbreviation: p q s : A ⇒ B ⇒ C
Blame calculus: Compatibility Γ ⊢ M : A A ≺ B p Γ ⊢ ( M : A ⇒ B ) : B A ≺ ⋆ ⋆ ≺ A ι ≺ ι A ′ ≺ A B ≺ B ′ A → B ≺ A ′ → B ′
Reductions Ground types G ::= ι | ⋆ → ⋆ p p p ⇒ A ′ → B ′ ) W ( V ( W : A ′ ⇒ B ′ ) ( V : A → B − → ⇒ A ) : B p V : ι ⇒ ι − → V p p V : A ⇒ ⋆ − → V : A ⇒ G ⇒ ⋆ if ⋆ � = A ≺ G p V : G ⇒ A if G ≺ A p V : G ⇒ ⋆ ⇒ A − → blame p if G �≺ A
Blame p ⌈ 2 ⌉ : ⋆ ⇒ Int = p 2 : Int ⇒ ⋆ ⇒ Int − → 2 p ⌈ true ⌉ : ⋆ ⇒ Int = p true : Bool ⇒ ⋆ ⇒ Int − → blame p
The Blame Game—widening p (( λy : Int . y + 1 ) : Int → Int ⇒ ⋆ → ⋆ ) ⌈ 2 ⌉ − → p p ( λy : Int . y + 1 ) ( ⌈ 2 ⌉ : ⋆ ⇒ Int ) : Int ⇒ ⋆ − → ⌈ 3 ⌉
The Blame Game—widening p (( λy : Int . y + 1 ) : Int → Int ⇒ ⋆ → ⋆ ) ⌈ true ⌉ − → p p ( λy : Int . y + 1 ) ( ⌈ true ⌉ : ⋆ ⇒ Int ) : Int ⇒ ⋆ − → blame p Widening can give rise to negative blame, but never positive blame
The Blame Game—narrowing p (( λy : ⋆. ⌈ y + 1 ⌉ ) : ⋆ → ⋆ ⇒ Int → Int ) 2 − → p p ( λy : ⋆. ⌈ y + 1 ⌉ ) ( 2 : Int ⇒ ⋆ ) : ⋆ ⇒ Int − → 3
The Blame Game—narrowing p (( λy : ⋆. ⌈ false ⌉ ) : ⋆ → ⋆ ⇒ Int → Int ) 2 − → p p ( λy : ⋆. ⌈ false ⌉ ) ( 2 : Int ⇒ ⋆ ) : ⋆ ⇒ Int − → blame p Narrowing can give rise to positive blame, but never negative blame
Part IV Subtyping < : + < : − < : < : n
Subtype ⋆ < : ⋆ A < : G A < : ⋆ ι < : ι A ′ < : A B < : B ′ A → B < : A ′ → B ′ Example: Int < : Int Int < : Int Int < : ⋆ Int < : ⋆ ⋆ → Int < : Int → ⋆
Positive subtype—widening A < : + ⋆ ι < : ι A ′ < : − A B < : + B ′ A → B < : + A ′ → B ′ Example: Int < : + ⋆ ⋆ < : − Int Int → Int < : ⋆ → ⋆
Negative subtype—narrowing ⋆ < : − A A < : − G A < : − ⋆ ι < : ι A ′ < : + A B < : − B ′ A → B < : − A ′ → B ′ Example: Int < : + ⋆ ⋆ < : − Int ⋆ → ⋆ < : − Int → Int
Naive subtype A < : n ⋆ ι < : n ι A < : n A ′ B < : n B ′ A → B < : n A ′ → B ′ Example: Int < : n ⋆ Int < : n ⋆ Int → Int < : n ⋆ → ⋆
Part V The Blame Theorem
Blame Safety N safe p L safe p M safe p λx. N safe p L M safe p x safe p A < : + B M safe p p M : A ⇒ B safe p A < : − B M safe p p M : A ⇒ B safe p s safe p p � = q p � = q ¯ q M : A ⇒ B safe p
The Blame Theorem Preservation If M safe p and M − → N then N safe p . Progress If M safe p then M � − → blame p .
The First Tangram Theorem A < : B if and only if A < : + B and A < : − B The First Blame Corollary p Let M be a term where N : A ⇒ B is the only subterm with label p . If A < : B then M � − → blame p and M � − → blame ¯ p .
The Second Tangram Theorem A < : n B if and only if A < : + B and B < : − A The Second Blame Corollary p Let M be a term where N : A ⇒ B is the only subterm with label p . If A < : n B then M � − → blame p . p Let M be a term where N : A ⇒ B is the only subterm with label p . If B < : n A then M � − → blame p .
Part VI Blame and coercions
Lambda calculus with coercions Γ ⊢ M : A c : A ⇒ B c Γ ⊢ M : A ⇒ B
Coercion typing id ( A ) : A ⇒ A ( G !) : G ⇒ ⋆ ( p ? G ) : ⋆ ⇒ G c : A ′ ⇒ A d : B ⇒ B ′ ( c → d ) : A → B ⇒ A ′ → B ′ c : A ⇒ B d : B ⇒ C ( c ; d ) : A ⇒ C
Blame safety is preserved and reflected p Let cast A ⇒ B translate to coercion c . A < : + B if and only if p does not appear in c . A < : − B if and only if ¯ p does not appear in c .
Part VII Polymorphism
A magic trick r :: [ a ] → [ a ]
Theorems for Free! [ a ] [ a ] r a ✲ r r map f map f ❄ ✲❄ r r r b [ b ] [ b ]
Theorems for Free! reverseInt [97,98,99] [99,98,97] ✲ r r map chr map chr ❄ ✲❄ r r reverseChar [’a’,’b’,’c’] [’c’,’b’,’a’]
Explicit binding Γ , X := A ⊢ N : B X / ∈ ftv( B ) Γ ⊢ νX := A. N : B Γ ⊢ N : B ( X := A ) ∈ Γ Γ ⊢ N : B [ X := A ] ( X := A ) ∈ Γ Γ ⊢ N : B [ X := A ] Γ ⊢ N : B (Λ X. N ) A − → νX := A. N Global store vs. Local bindings George Neis, Derek Dreyer, and Andreas Rossberg. Non-parametric parametricity. ICFP 2009, Edinburgh.
Compatibility and reductions A ≺ B A [ X := ⋆ ] ≺ B A ≺ ∀ X. B X / ∈ ftv ( A ) ∀ X. A ≺ B X ≺ X p p V : A ⇒ ( ∀ X. B ) − → Λ X. ( V : A ⇒ B ) if X / ∈ ftv ( A ) p p V : ( ∀ X. A ) ⇒ B − → ( V ⋆ ) : A [ X := ⋆ ] ⇒ B p q V : X ⇒ ⋆ ⇒ X − → V p q V : X ⇒ ⋆ ⇒ Y − → blame q if X � = Y
Instantiate p p V : ∀ X. A ⇒ B − → V ⋆ : A [ X := ⋆ ] ⇒ B K = λx : X. λy : X. x p (((Λ X. K ) : ∀ X. X → X → X ⇒ ⋆ → ⋆ → ⋆ ) 42 7 p − → (((Λ X. K ) ⋆ : ⋆ → ⋆ → ⋆ ⇒ ⋆ → ⋆ → ⋆ ) 42 7 p − → νX := ⋆. ( K : ⋆ → ⋆ → ⋆ ⇒ ⋆ → ⋆ → ⋆ ) 42 7 p p p − → νX := ⋆. ( K ( 42 : ⋆ ⇒ ⋆ ) ( 7 : ⋆ ⇒ ⋆ )) : ⋆ ⇒ ⋆ p p − → νX := ⋆. ( 42 : ⋆ ⇒ ⋆ ) : ⋆ ⇒ ⋆ − → νX := ⋆. 42 − → 42
⋆ is a Jack-of-all-Trades p p V : ∀ X. A ⇒ B − → V ⋆ : A [ X := ⋆ ] ⇒ B K = λx : X. λy : X. x p ((Λ X. K ) : ∀ X. X → X → X ⇒ Int → Int → Int ) 42 7 p − → ((Λ X. K ) ⋆ : ⋆ → ⋆ → ⋆ ⇒ Int → Int → Int ) 42 7 p − → νX := ⋆. ( K : ⋆ → ⋆ → ⋆ ⇒ Int → Int → Int ) 42 7 p p p − → νX := ⋆. ( K ( 42 : Int ⇒ ⋆ ) ( 7 : Int ⇒ ⋆ )) : ⋆ ⇒ Int p p − → νX := ⋆. ( 42 : Int ⇒ ⋆ ) : ⋆ ⇒ Int − → νX := ⋆. 42 − → 42
... but master of none p p V : ∀ X. A ⇒ B − → V ⋆ : A [ X := ⋆ ] ⇒ B K = λx : X. λy : X. x p ((Λ X. K ) : ∀ X. X → X → X ⇒ Int → Bool → Int ) 42 true p − → ((Λ X. K ) ⋆ : ⋆ → ⋆ → ⋆ ⇒ Int → Bool → Int ) 42 true p − → νX := ⋆. ( K : ⋆ → ⋆ → ⋆ ⇒ Int → Bool → Int ) 42 true p p p − → νX := ⋆. ( K ( 42 : Int ⇒ ⋆ ) ( true : Bool ⇒ ⋆ )) : ⋆ ⇒ Int p p − → νX := ⋆. ( 42 : Int ⇒ ⋆ ) : ⋆ ⇒ Int − → νX := ⋆. 42 − → 42
Recommend
More recommend