Circular vs. Higher-Order Shortcut Fusion Janis Voigtl¨ ander Technische Universit¨ at Dresden March 30th, 2009
Classical Shortcut Fusion [Gill et al., FPCA’93] Example: upTo n = go 1 where go i = if i > n then [ ] else i : go ( i + 1) 2
Classical Shortcut Fusion [Gill et al., FPCA’93] Example: upTo n = go 1 where go i = if i > n then [ ] else i : go ( i + 1) sum [ ] = 0 sum ( x : xs ) = x + sum xs 2
Classical Shortcut Fusion [Gill et al., FPCA’93] Example: upTo n = go 1 where go i = if i > n then [ ] else i : go ( i + 1) sum [ ] = 0 sum ( x : xs ) = x + sum xs Problem: Expressions like sum ( upTo 10) require explicit construction of intermediate results. 2
Classical Shortcut Fusion [Gill et al., FPCA’93] Example: upTo n = go 1 where go i = if i > n then [ ] else i : go ( i + 1) sum [ ] = 0 sum ( x : xs ) = x + sum xs Problem: Expressions like sum ( upTo 10) require explicit construction of intermediate results. Solution: 1. Write upTo in terms of build . 2
Classical Shortcut Fusion [Gill et al., FPCA’93] Example: upTo n = go 1 where go i = if i > n then [ ] else i : go ( i + 1) sum [ ] = 0 sum ( x : xs ) = x + sum xs Problem: Expressions like sum ( upTo 10) require explicit construction of intermediate results. Solution: 1. Write upTo in terms of build . 2. Write sum in terms of foldr . 2
Classical Shortcut Fusion [Gill et al., FPCA’93] Example: upTo n = go 1 where go i = if i > n then [ ] else i : go ( i + 1) sum [ ] = 0 sum ( x : xs ) = x + sum xs Problem: Expressions like sum ( upTo 10) require explicit construction of intermediate results. Solution: 1. Write upTo in terms of build . 2. Write sum in terms of foldr . 3. Use the following fusion rule: foldr h 1 h 2 ( build g ) � g h 1 h 2 2
Circular Shortcut Fusion [Fernandes et al., Haskell’07] Producing intermediate results: buildp :: ( ∀ a . ( b → a → a ) → a → c → ( a , z )) → c → ([ b ] , z ) buildp g c = g (:) [ ] c 3
Circular Shortcut Fusion [Fernandes et al., Haskell’07] Producing intermediate results: buildp :: ( ∀ a . ( b → a → a ) → a → c → ( a , z )) → c → ([ b ] , z ) buildp g c = g (:) [ ] c filterAndCount :: ( b → Bool ) → [ b ] → ([ b ] , Int ) filterAndCount f = buildp · · · 3
Circular Shortcut Fusion [Fernandes et al., Haskell’07] Producing intermediate results: buildp :: ( ∀ a . ( b → a → a ) → a → c → ( a , z )) → c → ([ b ] , z ) buildp g c = g (:) [ ] c Consuming intermediate results: pfold :: ( b → a → z → a ) → ( z → a ) → ([ b ] , z ) → a pfold h 1 h 2 ( bs , z ) = foldr ( λ b a → h 1 b a z ) ( h 2 z ) bs 3
Circular Shortcut Fusion [Fernandes et al., Haskell’07] Producing intermediate results: buildp :: ( ∀ a . ( b → a → a ) → a → c → ( a , z )) → c → ([ b ] , z ) buildp g c = g (:) [ ] c Consuming intermediate results: pfold :: ( b → a → z → a ) → ( z → a ) → ([ b ] , z ) → a pfold h 1 h 2 ( bs , z ) = foldr ( λ b a → h 1 b a z ) ( h 2 z ) bs normalise :: ([ Int ] , Int ) → [ Float ] normalise = pfold · · · 3
Circular Shortcut Fusion [Fernandes et al., Haskell’07] Producing intermediate results: buildp :: ( ∀ a . ( b → a → a ) → a → c → ( a , z )) → c → ([ b ] , z ) buildp g c = g (:) [ ] c Consuming intermediate results: pfold :: ( b → a → z → a ) → ( z → a ) → ([ b ] , z ) → a pfold h 1 h 2 ( bs , z ) = foldr ( λ b a → h 1 b a z ) ( h 2 z ) bs The fusion rule: pfold h 1 h 2 ( buildp g c ) � let ( a , z ) = g ( λ b a → h 1 b a z ) ( h 2 z ) c in a 3
Circular Shortcut Fusion [Fernandes et al., Haskell’07] Producing intermediate results: buildp :: ( ∀ a . ( b → a → a ) → a → c → ( a , z )) → c → ([ b ] , z ) buildp g c = g (:) [ ] c Consuming intermediate results: pfold :: ( b → a → z → a ) → ( z → a ) → ([ b ] , z ) → a pfold h 1 h 2 ( bs , z ) = foldr ( λ b a → h 1 b a z ) ( h 2 z ) bs The fusion rule: pfold h 1 h 2 ( buildp g c ) � let ( a , z ) = g ( λ b a → h 1 b a z ) ( h 2 z ) c in a 3
Circular Shortcut Fusion [Fernandes et al., Haskell’07] Producing intermediate results: buildp :: ( ∀ a . ( b → a → a ) → a → c → ( a , z )) → c → ([ b ] , z ) buildp g c = g (:) [ ] c 4
Circular Shortcut Fusion [Fernandes et al., Haskell’07] Producing intermediate results: buildp :: ( ∀ a . ( b → a → a ) → a → c → ( a , z )) → c → ([ b ] , z ) buildp g c = g (:) [ ] c The type of g forces it to be essentially of the following form: , λ con nil c → con z con b 1 b 2 con b n nil 4
Circular Shortcut Fusion [Fernandes et al., Haskell’07] Producing intermediate results: buildp :: ( ∀ a . ( b → a → a ) → a → c → ( a , z )) → c → ([ b ] , z ) buildp g c = g (:) [ ] c The type of g forces it to be essentially of the following form: , λ con nil c → con z con b 1 b 2 con b n nil Formal justification: free theorems [Wadler, FPCA’89] 4
Circular Shortcut Fusion [Fernandes et al., Haskell’07] Consuming intermediate results: pfold :: ( b → a → z → a ) → ( z → a ) → ([ b ] , z ) → a pfold h 1 h 2 ( bs , z ) = foldr ( λ b a → h 1 b a z ) ( h 2 z ) bs A concrete output ( buildp g c ) will be consumed as follows: , h 1 : z b 1 h 1 z : b 1 b 2 z �→ b 2 h 1 : z b n h 2 b n [ ] z 5
Circular Shortcut Fusion [Fernandes et al., Haskell’07] pfold h 1 h 2 ( g (:) [ ] c ) � h 1 z b 1 h 1 z b 2 � h 1 b n h 2 z z 6
Circular Shortcut Fusion [Fernandes et al., Haskell’07] pfold h 1 h 2 ( g (:) [ ] c ) � let ( a , z ) = g ( λ b a → h 1 b a z ) ( h 2 z ) c in a snd fst , h 1 z h 1 z b 1 h 1 b 1 h 1 z b 2 � b 2 h 1 h 1 b n h 2 z b n h 2 z 6
Circular Shortcut Fusion [Fernandes et al., Haskell’07] pfold h 1 h 2 ( g (:) [ ] c ) � let ( a , z ) = g ( λ b a → h 1 b a z ) ( h 2 z ) c in a snd , h 1 h 1 z z b 1 h 1 b 1 h 1 z b 2 � b 2 h 1 h 1 b n h 2 z b n h 2 z 6
Circular Shortcut Fusion [Fernandes et al., Haskell’07] pfold h 1 h 2 ( g (:) [ ] c ) � let ( a , z ) = g ( λ b a → h 1 b a z ) ( h 2 z ) c in a h 1 h 1 z b 1 h 1 b 1 h 1 z z b 2 � b 2 h 1 h 1 b n h 2 z b n h 2 z 6
This is Where I got Interested ◮ Free-theorems-based transformations had been studied before. 7
This is Where I got Interested ◮ Free-theorems-based transformations had been studied before. ◮ . . . but been found to not be totally correct when considering certain language features [Johann and V., POPL’04]. 7
This is Where I got Interested ◮ Free-theorems-based transformations had been studied before. ◮ . . . but been found to not be totally correct when considering certain language features [Johann and V., POPL’04]. ◮ Circular shortcut fusion depends on evaluation order, which is precisely a “dangerous” corner for free theorems. 7
This is Where I got Interested ◮ Free-theorems-based transformations had been studied before. ◮ . . . but been found to not be totally correct when considering certain language features [Johann and V., POPL’04]. ◮ Circular shortcut fusion depends on evaluation order, which is precisely a “dangerous” corner for free theorems. ◮ So would it be possible to manufacture counterexamples? 7
A Problem with Selective Strictness Producing intermediate results: buildp :: ( ∀ a . ( b → a → a ) → a → c → ( a , z )) → c → ([ b ] , z ) buildp g c = g (:) [ ] c In Haskell, g could also be, for example, of the following form: seq λ con nil c → , nil con z con b 1 b 2 con b n nil 8
A Problem with Selective Strictness Producing intermediate results: buildp :: ( ∀ a . ( b → a → a ) → a → c → ( a , z )) → c → ([ b ] , z ) buildp g c = g (:) [ ] c The type of g forces it to be essentially of the following form: , λ con nil c → con z con b 1 b 2 con b n nil 9
A Problem with Selective Strictness Producing intermediate results: buildp :: ( ∀ a . ( b → a → a ) → a → c → ( a , z )) → c → ([ b ] , z ) buildp g c = g (:) [ ] c In Haskell, g could also be, for example, of the following form: seq λ con nil c → , nil con z con b 1 b 2 con b n nil 10
A Problem with Selective Strictness This would lead to the following replacement: h 1 b 1 h 1 z z b 2 � h 1 b n h 2 z z 11
A Problem with Selective Strictness This would lead to the following replacement: snd fst h 1 seq b 1 h 1 z , h 2 z b 2 z h 1 � h 1 b 1 h 1 b n h 2 z b 2 z h 1 b n 11
A Problem with Selective Strictness This would lead to the following replacement: snd fst h 1 seq b 1 h 1 z , h 2 z b 2 z h 1 � h 1 b 1 h 1 b n h 2 z b 2 z h 1 b n 11
A Problem with Selective Strictness This would lead to the following replacement: snd fst h 1 seq b 1 h 1 z , h 2 z b 2 z h 1 � h 1 b 1 h 1 b n h 2 z b 2 z h 1 b n 11
A Problem with Selective Strictness This would lead to the following replacement: snd fst h 1 seq b 1 h 1 z , h 2 z b 2 z h 1 � h 1 b 1 h 1 b n h 2 z b 2 z h 1 b n 11
A Problem with Selective Strictness This would lead to the following replacement: snd fst h 1 seq b 1 h 1 z , h 2 z b 2 z h 1 � h 1 b 1 h 1 b n h 2 z b 2 z h 1 b n 11
Recommend
More recommend