Retrofitting Purity with Comonads Neel Krishnaswami June 25, 2018 University of Cambridge
Once Upon a Time • There was a PhD student • who finished her dissertation… 1
Once Upon a Time • There was a PhD student • who finished her dissertation… 1
Once Upon a Time • There was a PhD student • who finished her dissertation… 1
Once Upon a Time • Her advisor said, “It’s time for you to go out into the wide world!” • So she did, and she designed a programming language 2
Once Upon a Time • Her advisor said, “It’s time for you to go out into the wide world!” • So she did, and she designed a programming language 2
Once Upon a Time • Her advisor said, “It’s time for you to go out into the wide world!” • So she did, and she designed a programming language 2
len : List a -> Integer map : (a -> b) -> List a -> List b map f [] A Functional Language data List a = [] | a :: ( List a) len [] = 0 len (x :: xs) = 1 + len xs = [] map f (x :: xs) = f x :: map f xs 3
map : (a -> b) -> List a -> List b map f [] A Functional Language data List a = [] | a :: ( List a) len [] = 0 len (x :: xs) = 1 + len xs = [] map f (x :: xs) = f x :: map f xs 3 len : List a -> Integer
A Functional Language data List a = [] | a :: ( List a) len [] = 0 len (x :: xs) = 1 + len xs = [] map f (x :: xs) = f x :: map f xs 3 len : List a -> Integer map : (a -> b) -> List a -> List b map f []
Once Upon a Time • While implementing it, she added one primitive: print : String -> Unit print = Runtime . Primitive . Magic .__printf • Nothing bad happened…yet! 4
Once Upon a Time • While implementing it, she added one primitive: print : String -> Unit print = Runtime . Primitive . Magic .__printf • Nothing bad happened…yet! 4
Once Upon a Time • While implementing it, she added one primitive: print : String -> Unit print = Runtime . Primitive . Magic .__printf • Nothing bad happened…yet! 4
Once Upon a Time • While implementing it, she added one primitive: print : String -> Unit print = Runtime . Primitive . Magic .__printf • Nothing bad happened… yet! 4
Once Upon a Time • While implementing it, she added one primitive: print : String -> Unit print = Runtime . Primitive . Magic .__printf • Nothing bad happened…yet! 4
Once Upon a Time • Naturally, this language was wildly successful • Our protagonist achieved fame and fortune • …and feature requests and bug reports 5
Once Upon a Time • Naturally, this language was wildly successful • Our protagonist achieved fame and fortune • …and feature requests and bug reports 5
Once Upon a Time • Naturally, this language was wildly successful • Our protagonist achieved fame and fortune • …and feature requests and bug reports 5
Once Upon a Time • Naturally, this language was wildly successful • Our protagonist achieved fame and fortune • …and feature requests and bug reports 5
Feature Request: List Fusion • A user wrote the following code: map f (map g reallyBigList) • and complained that it allocated a really big intermediate list 6
Feature Request: List Fusion • Our protagonist wrote a compiler pass to turn this: map f (map g reallyBigList) • into this: map (f o g) reallyBigList • Much RAM was saved! • Benchmarks improved! 7
Feature Request: List Fusion • Our protagonist wrote a compiler pass to turn this: map f (map g reallyBigList) • into this: map (f o g) reallyBigList • Much RAM was saved! • Benchmarks improved! 7
Feature Request: List Fusion • Our protagonist wrote a compiler pass to turn this: map f (map g reallyBigList) • into this: map (f o g) reallyBigList • Much RAM was saved! • Benchmarks improved! 7
Feature Request: List Fusion • Our protagonist wrote a compiler pass to turn this: map f (map g reallyBigList) • into this: map (f o g) reallyBigList • Much RAM was saved! • Benchmarks improved! 7
Feature Request: List Fusion • Our protagonist wrote a compiler pass to turn this: map f (map g reallyBigList) • into this: map (f o g) reallyBigList • Much RAM was saved! • Benchmarks improved! 7
f : Int -> Int Bug Reports • This code f n = print "a"; n + 1 g : Int -> Int g n = print "b"; n + 1 printList (map f (map g [1, 2, 3])) • In the old version, it printed: bbbaaa[3, 4, 5] • In the “optimized” version, it printed: bababa[3, 4, 5] 8
Bug Reports • This code f n = print "a"; n + 1 g : Int -> Int g n = print "b"; n + 1 printList (map f (map g [1, 2, 3])) • In the old version, it printed: bbbaaa[3, 4, 5] • In the “optimized” version, it printed: bababa[3, 4, 5] 8 f : Int -> Int
Bug Reports • This code f n = print "a"; n + 1 g : Int -> Int g n = print "b"; n + 1 printList (map f (map g [1, 2, 3])) • In the old version, it printed: bbbaaa[3, 4, 5] • In the “optimized” version, it printed: bababa[3, 4, 5] 8 f : Int -> Int
Bug Reports • This code f n = print "a"; n + 1 g : Int -> Int g n = print "b"; n + 1 printList (map f (map g [1, 2, 3])) • In the old version, it printed: bbbaaa[3, 4, 5] • In the “optimized” version, it printed: bababa[3, 4, 5] 8 f : Int -> Int
Narrative Tension! • Our protagonist was worried: • She wanted purity for optimization purposes • But her language was already impure • Was she out of luck? 9
Narrative Tension! • Our protagonist was worried: • She wanted purity for optimization purposes • But her language was already impure • Was she out of luck? 9
Narrative Tension! • Our protagonist was worried: • She wanted purity for optimization purposes • But her language was already impure • Was she out of luck? 9
Narrative Tension! • Our protagonist was worried: • She wanted purity for optimization purposes • But her language was already impure • Was she out of luck? 9
Narrative Tension! • Our protagonist was worried: • She wanted purity for optimization purposes • But her language was already impure • Was she out of luck? 9
Syntax pure e Judgements A x Contexts e in e Types let pure x e Terms Pure A A 10 File | char | A → B ::= ::= x | c | e . print ( e ′ ) | λ x . e | e e ′ Γ ::= · | Γ , x : A Γ ⊢ e : A
Syntax e Judgements Contexts Types 10 Terms A File | char | A → B | Pure A ::= ::= x | c | e . print ( e ′ ) | λ x . e | e e ′ | pure ( e ) | let pure ( x ) = e in e ′ Γ ::= · | Γ , x : A | Γ , x :: A Γ ⊢ e : A
A pure A pure pure x Typing Rules e in e A e C let pure x x C pure Pure A pure x A x e 11 Pure A pure e A e pure x A Γ ⊢ e ′ : char x : A ∈ Γ Γ ⊢ e : File Γ ⊢ x : A Γ ⊢ e . print ( e ′ ) : 1 Γ ⊢ e ′ : A Γ , x : A ⊢ e : B Γ ⊢ e : A → B Γ ⊢ e e ′ : B Γ ⊢ λ x . e : A → B
A pure A pure pure x Typing Rules x A x pure x pure C e in e let pure x C e A Pure A 11 e Pure A pure e A e pure Γ ⊢ e ′ : char x : A ∈ Γ ∨ x :: A ∈ Γ Γ ⊢ e : File Γ ⊢ x : A Γ ⊢ e . print ( e ′ ) : 1 Γ ⊢ e ′ : A Γ , x : A ⊢ e : B Γ ⊢ e : A → B Γ ⊢ e e ′ : B Γ ⊢ λ x . e : A → B
Typing Rules e C e in e let pure x C e x Pure A A 11 Γ ⊢ e ′ : char x : A ∈ Γ ∨ x :: A ∈ Γ Γ ⊢ e : File Γ ⊢ x : A Γ ⊢ e . print ( e ′ ) : 1 Γ ⊢ e ′ : A Γ , x : A ⊢ e : B Γ ⊢ e : A → B Γ ⊢ e e ′ : B Γ ⊢ λ x . e : A → B Γ pure ⊢ e : A Γ ⊢ pure ( e ) : Pure ( A ) ( · ) pure = · (Γ , x : A ) pure = Γ pure (Γ , x :: A ) pure = Γ pure , x :: A
Typing Rules 11 Γ ⊢ e ′ : char x : A ∈ Γ ∨ x :: A ∈ Γ Γ ⊢ e : File Γ ⊢ x : A Γ ⊢ e . print ( e ′ ) : 1 Γ ⊢ e ′ : A Γ , x : A ⊢ e : B Γ ⊢ e : A → B Γ ⊢ e e ′ : B Γ ⊢ λ x . e : A → B Γ pure ⊢ e : A Γ , x :: A ⊢ e ′ : C Γ ⊢ e : Pure ( A ) Γ ⊢ let pure ( x ) = e in e ′ : C Γ ⊢ pure ( e ) : Pure ( A ) ( · ) pure = · (Γ , x : A ) pure = Γ pure (Γ , x :: A ) pure = Γ pure , x :: A
A Pure Map Function data List a = [] | a :: ( List a) map : Pure (a -> b) -> List a -> List b map (pure f) [] = [] map (pure f) (x :: xs) = f x :: map (pure f) xs 12
A Pure Map Function data List a = [] | a :: ( List a) map : Pure (a -> b) -> List a -> List b map (pure f) [] = [] map (pure f) (x :: xs) = f x :: map (pure f) xs 12
• Imperative functions like print are bound to ordinary Principles of Retrofitted Purity • We have ordinary and pure variables • We add a type for “pure values” • Pure values can only refer to pure variables variables • But does this work? 13
• Imperative functions like print are bound to ordinary Principles of Retrofitted Purity • We have ordinary and pure variables • We add a type for “pure values” • Pure values can only refer to pure variables variables • But does this work? 13
Recommend
More recommend