Circular vs. Higher-Order Shortcut Fusion Janis Voigtl ander - - PowerPoint PPT Presentation

circular vs higher order shortcut fusion
SMART_READER_LITE
LIVE PREVIEW

Circular vs. Higher-Order Shortcut Fusion Janis Voigtl ander - - PowerPoint PPT Presentation

Circular vs. Higher-Order Shortcut Fusion Janis Voigtl ander Technische Universit at Dresden March 30th, 2009 Classical Shortcut Fusion [Gill et al., FPCA93] Example: upTo n = go 1 where go i = if i > n then [ ] else i : go ( i + 1)


slide-1
SLIDE 1

Circular vs. Higher-Order Shortcut Fusion

Janis Voigtl¨ ander

Technische Universit¨ at Dresden

March 30th, 2009

slide-2
SLIDE 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)

2

slide-3
SLIDE 3

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

slide-4
SLIDE 4

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

slide-5
SLIDE 5

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

slide-6
SLIDE 6

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

slide-7
SLIDE 7

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 h1 h2 (build g) g h1 h2

2

slide-8
SLIDE 8

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

slide-9
SLIDE 9

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

slide-10
SLIDE 10

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 h1 h2 (bs, z) = foldr (λb a → h1 b a z) (h2 z) bs

3

slide-11
SLIDE 11

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 h1 h2 (bs, z) = foldr (λb a → h1 b a z) (h2 z) bs normalise :: ([Int], Int) → [Float] normalise = pfold · · ·

3

slide-12
SLIDE 12

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 h1 h2 (bs, z) = foldr (λb a → h1 b a z) (h2 z) bs The fusion rule: pfold h1 h2 (buildp g c)

  • let (a, z) = g (λb a → h1 b a z) (h2 z) c in a

3

slide-13
SLIDE 13

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 h1 h2 (bs, z) = foldr (λb a → h1 b a z) (h2 z) bs The fusion rule: pfold h1 h2 (buildp g c)

  • let (a, z) = g (λb a → h1 b a z) (h2 z) c in a

3

slide-14
SLIDE 14

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

slide-15
SLIDE 15

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 b1 con b2 con bn nil z

4

slide-16
SLIDE 16

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 b1 con b2 con bn nil z Formal justification: free theorems [Wadler, FPCA’89]

4

slide-17
SLIDE 17

Circular Shortcut Fusion [Fernandes et al., Haskell’07]

Consuming intermediate results: pfold :: (b → a → z → a) → (z → a) → ([b], z) → a pfold h1 h2 (bs, z) = foldr (λb a → h1 b a z) (h2 z) bs A concrete output (buildp g c) will be consumed as follows: , : b1 : b2 : bn [ ] z → h1 b1 h1 b2 h1 bn h2 z z z z

5

slide-18
SLIDE 18

Circular Shortcut Fusion [Fernandes et al., Haskell’07]

pfold h1 h2 (g (:) [ ] c) h1 b1 h1 b2 h1 bn h2 z z z z

  • 6
slide-19
SLIDE 19

Circular Shortcut Fusion [Fernandes et al., Haskell’07]

pfold h1 h2 (g (:) [ ] c) let (a, z) = g (λb a → h1 b a z) (h2 z) c in a h1 b1 h1 b2 h1 bn h2 z z z z

  • fst

, h1 b1 h1 b2 h1 bn h2 z snd

6

slide-20
SLIDE 20

Circular Shortcut Fusion [Fernandes et al., Haskell’07]

pfold h1 h2 (g (:) [ ] c) let (a, z) = g (λb a → h1 b a z) (h2 z) c in a h1 b1 h1 b2 h1 bn h2 z z z z

  • snd

, h1 b1 h1 b2 h1 bn h2 z

6

slide-21
SLIDE 21

Circular Shortcut Fusion [Fernandes et al., Haskell’07]

pfold h1 h2 (g (:) [ ] c) let (a, z) = g (λb a → h1 b a z) (h2 z) c in a h1 b1 h1 b2 h1 bn h2 z z z z

  • h1

b1 h1 b2 h1 bn h2 z

6

slide-22
SLIDE 22

This is Where I got Interested

◮ Free-theorems-based transformations had been studied before.

7

slide-23
SLIDE 23

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

slide-24
SLIDE 24

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

slide-25
SLIDE 25

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

slide-26
SLIDE 26

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: λcon nil c → seq nil , con b1 con b2 con bn nil z

8

slide-27
SLIDE 27

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 b1 con b2 con bn nil z

9

slide-28
SLIDE 28

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: λcon nil c → seq nil , con b1 con b2 con bn nil z

10

slide-29
SLIDE 29

A Problem with Selective Strictness

This would lead to the following replacement: h1 b1 h1 b2 h1 bn h2 z z z z

  • 11
slide-30
SLIDE 30

A Problem with Selective Strictness

This would lead to the following replacement: h1 b1 h1 b2 h1 bn h2 z z z z

  • fst

seq h2 , h1 b1 h1 b2 h1 bn z snd

11

slide-31
SLIDE 31

A Problem with Selective Strictness

This would lead to the following replacement: h1 b1 h1 b2 h1 bn h2 z z z z

  • fst

seq h2 , h1 b1 h1 b2 h1 bn z snd

11

slide-32
SLIDE 32

A Problem with Selective Strictness

This would lead to the following replacement: h1 b1 h1 b2 h1 bn h2 z z z z

  • fst

seq h2 , h1 b1 h1 b2 h1 bn z snd

11

slide-33
SLIDE 33

A Problem with Selective Strictness

This would lead to the following replacement: h1 b1 h1 b2 h1 bn h2 z z z z

  • fst

seq h2 , h1 b1 h1 b2 h1 bn z snd

11

slide-34
SLIDE 34

A Problem with Selective Strictness

This would lead to the following replacement: h1 b1 h1 b2 h1 bn h2 z z z z

  • fst

seq h2 , h1 b1 h1 b2 h1 bn z snd

11

slide-35
SLIDE 35

A Problem with Selective Strictness

This would lead to the following replacement: h1 b1 h1 b2 h1 bn h2 z z z z

  • fst

seq h2 , h1 b1 h1 b2 h1 bn z snd

11

slide-36
SLIDE 36

Total and Partial Correctness [V., FLOPS’08]

Theorem 1

If h2 ⊥ = ⊥ and h1 ⊥ ⊥ ⊥ = ⊥, then pfold h1 h2 (buildp g c) = let (a, z) = g (λb a → h1 b a z) (h2 z) c in a

12

slide-37
SLIDE 37

Total and Partial Correctness [V., FLOPS’08]

Theorem 1

If h2 ⊥ = ⊥ and h1 ⊥ ⊥ ⊥ = ⊥, then pfold h1 h2 (buildp g c) = let (a, z) = g (λb a → h1 b a z) (h2 z) c in a

Theorem 2

Without preconditions, pfold h1 h2 (buildp g c) ⊒ let (a, z) = g (λb a → h1 b a z) (h2 z) c in a

12

slide-38
SLIDE 38

Replacing Circularity by Higher-Orderedness

pfold h1 h2 (g (:) [ ] c) let (a, z) = g (λb a → h1 b a z) (h2 z) c in a

13

slide-39
SLIDE 39

Replacing Circularity by Higher-Orderedness

pfold h1 h2 (g (:) [ ] c) let (a, z) = g (λb a → h1 b a z) (h2 z) c in a case g (λb k z → h1 b (k z) z) (λz → h2 z) c

  • f (k, z) → k z

13

slide-40
SLIDE 40

Replacing Circularity by Higher-Orderedness

pfold h1 h2 (g (:) [ ] c) case g (λb k z → h1 b (k z) z) (λz → h2 z) c

  • f (k, z) → k z

, λ h1 b1 $ λ h1 bn $ λ h2 z $ fst snd

h1 b1 h1 b2 h1 bn h2 z z z z

  • 13
slide-41
SLIDE 41

Replacing Circularity by Higher-Orderedness

pfold h1 h2 (g (:) [ ] c) case g (λb k z → h1 b (k z) z) (λz → h2 z) c

  • f (k, z) → k z

, λ h1 b1 $ λ h1 bn $ λ h2 z $ snd

h1 b1 h1 b2 h1 bn h2 z z z z

  • 13
slide-42
SLIDE 42

Replacing Circularity by Higher-Orderedness

pfold h1 h2 (g (:) [ ] c) case g (λb k z → h1 b (k z) z) (λz → h2 z) c

  • f (k, z) → k z

h1 b1 $ λ h1 b2 $ λ h1 bn $ λ h2 z

h1 b1 h1 b2 h1 bn h2 z z z z

  • 13
slide-43
SLIDE 43

Replacing Circularity by Higher-Orderedness

pfold h1 h2 (g (:) [ ] c) case g (λb k z → h1 b (k z) z) (λz → h2 z) c

  • f (k, z) → k z

h1 b1 h1 b2 $ λ h1 bn $ λ h2 z

h1 b1 h1 b2 h1 bn h2 z z z z

  • 13
slide-44
SLIDE 44

Replacing Circularity by Higher-Orderedness

pfold h1 h2 (g (:) [ ] c) case g (λb k z → h1 b (k z) z) (λz → h2 z) c

  • f (k, z) → k z

h1 b1 h1 b2 h1 bn $ λ h2 z

h1 b1 h1 b2 h1 bn h2 z z z z

  • 13
slide-45
SLIDE 45

Replacing Circularity by Higher-Orderedness

pfold h1 h2 (g (:) [ ] c) case g (λb k z → h1 b (k z) z) (λz → h2 z) c

  • f (k, z) → k z

h1 b1 h1 b2 h1 bn h2 z

h1 b1 h1 b2 h1 bn h2 z z z z

  • 13
slide-46
SLIDE 46

No Problem with Selective Strictness

For a g of the problematic form considered earlier: h1 b1 h1 b2 h1 bn h2 z z z z

  • seq

λ h2 , λ h1 b1 $ λ h1 bn $ z $ fst snd

14

slide-47
SLIDE 47

Total Correctness [V., FLOPS’08]

Theorem 3

Without preconditions, pfold h1 h2 (buildp g c) = case g (λb k z → h1 b (k z) z) (λz → h2 z) c of (k, z) → k z

15

slide-48
SLIDE 48

Total Correctness [V., FLOPS’08]

Theorem 3

Without preconditions, pfold h1 h2 (buildp g c) = case g (λb k z → h1 b (k z) z) (λz → h2 z) c of (k, z) → k z

15

slide-49
SLIDE 49

Circular vs. Higher-Order Shortcut Fusion

Which flavour is better?

16

slide-50
SLIDE 50

Circular vs. Higher-Order Shortcut Fusion

Which flavour is better?

◮ Intellectually, I find the circular approach more fascinating.

16

slide-51
SLIDE 51

Circular vs. Higher-Order Shortcut Fusion

Which flavour is better?

◮ Intellectually, I find the circular approach more fascinating. ◮ But semantically, the high-order approach is more robust.

16

slide-52
SLIDE 52

Circular vs. Higher-Order Shortcut Fusion

Which flavour is better?

◮ Intellectually, I find the circular approach more fascinating. ◮ But semantically, the high-order approach is more robust. ◮ Performance measurements do not give a very clear picture.

16

slide-53
SLIDE 53

Circular vs. Higher-Order Shortcut Fusion

Which flavour is better?

◮ Intellectually, I find the circular approach more fascinating. ◮ But semantically, the high-order approach is more robust. ◮ Performance measurements do not give a very clear picture. ◮ There are interesting interactions with rather low-level details

  • f the language implementation!

16

slide-54
SLIDE 54

Tricky Sharing Issues — Circular Shortcut Fusion

pfold h1 h2 (buildp g c) let (a, z) = g (λb a → h1 b a z) (h2 z) c in a

17

slide-55
SLIDE 55

Tricky Sharing Issues — Circular Shortcut Fusion

pfold h1 h2 (buildp g c) let (a, z) = g (λb a → h1 b a z) (h2 z) c in a If h1 = λb a z → h′

1 b a (h z),

17

slide-56
SLIDE 56

Tricky Sharing Issues — Circular Shortcut Fusion

pfold h1 h2 (buildp g c) let (a, z) = g (λb a → h1 b a z) (h2 z) c in a If h1 = λb a z → h′

1 b a (h z), then:

h′

1

b1 h′

1

b2 h′

1

bn h2 z h z h z h z

  • fst

, h′

1

b1 h′

1

b2 h′

1

bn h2 h h h z snd

17

slide-57
SLIDE 57

Tricky Sharing Issues — Circular Shortcut Fusion

pfold h1 h2 (buildp g c) let (a, z) = g (λb a → h1 b a z) (h2 z) c in a If h1 = λb a z → h′

1 b a (h z), then using full laziness:

h′

1

b1 h′

1

b2 h′

1

bn h2 z h z

  • fst

, h′

1

b1 h′

1

b2 h′

1

bn h2 h z snd

17

slide-58
SLIDE 58

Tricky Sharing Issues — Higher-Order Shortcut Fusion

pfold h1 h2 (buildp g c) case g (λb k z → h1 b (k z) z) (λz → h2 z) c

  • f (k, z) → k z

If h1 = λb a z → h′

1 b a (h z), then:

h′

1

b1 h′

1

b2 h′

1

bn h2 z h z h z h z

  • ,

λ h′

1

b1 $ λ h′

1

bn $ λ h2 h h z $ fst snd

18

slide-59
SLIDE 59

Tricky Sharing Issues — Higher-Order Shortcut Fusion

pfold h1 h2 (buildp g c) case g (λb k z → h1 b (k z) z) (λz → h2 z) c

  • f (k, z) → k z

If h1 = λb a z → h′

1 b a (h z), then using full laziness:

h′

1

b1 h′

1

b2 h′

1

bn h2 z h z

  • ,

λ h′

1

b1 $ λ h′

1

bn $ λ h2 h h z $ fst snd

18

slide-60
SLIDE 60

What can be Learnt

◮ Both semantic and pragmatic considerations can motivate

studying new rules as well as new combinators.

19

slide-61
SLIDE 61

What can be Learnt

◮ Both semantic and pragmatic considerations can motivate

studying new rules as well as new combinators.

◮ These lessons also inform new developments for more classical

shortcut fusion techniques.

19

slide-62
SLIDE 62

What can be Learnt

◮ Both semantic and pragmatic considerations can motivate

studying new rules as well as new combinators.

◮ These lessons also inform new developments for more classical

shortcut fusion techniques.

◮ There is still an interesting design space to explore!

19

slide-63
SLIDE 63

Recent (and Future?) Developments

◮ [Pardo et al., PEPM’09] study circular and higher-order

shortcut fusion in the presence of monads.

20

slide-64
SLIDE 64

Recent (and Future?) Developments

◮ [Pardo et al., PEPM’09] study circular and higher-order

shortcut fusion in the presence of monads.

◮ From a semantics perspective, the circular flavour is again

more intriguing.

20

slide-65
SLIDE 65

Recent (and Future?) Developments

◮ [Pardo et al., PEPM’09] study circular and higher-order

shortcut fusion in the presence of monads.

◮ From a semantics perspective, the circular flavour is again

more intriguing.

◮ The higher-order flavour is (again) more generally applicable.

20

slide-66
SLIDE 66

Recent (and Future?) Developments

◮ [Pardo et al., PEPM’09] study circular and higher-order

shortcut fusion in the presence of monads.

◮ From a semantics perspective, the circular flavour is again

more intriguing.

◮ The higher-order flavour is (again) more generally applicable. ◮ It should be interesting to investigate the interplay with other

fusion work involving monads [V., MPC’08].

20

slide-67
SLIDE 67

References I

J.P. Fernandes, A. Pardo, and J. Saraiva. A shortcut fusion rule for circular program calculation. In Haskell Workshop, Proceedings, pages 95–106. ACM Press, 2007.

  • A. Gill, J. Launchbury, and S.L. Peyton Jones.

A short cut to deforestation. In Functional Programming Languages and Computer Architecture, Proceedings, pages 223–232. ACM Press, 1993.

  • P. Johann and J. Voigtl¨

ander. Free theorems in the presence of seq. In Principles of Programming Languages, Proceedings, pages 99–110. ACM Press, 2004.

21

slide-68
SLIDE 68

References II

  • A. Pardo, J.P. Fernandes, and J. Saraiva.

Shortcut fusion rules for the derivation of circular and higher-order monadic programs. In Partial Evaluation and Program Manipulation, Proceedings, pages 81–90. ACM Press, 2009. S.L. Peyton Jones and D. Lester. A modular fully-lazy lambda lifter in Haskell. Software Practice and Experience, 21(5):479–506, 1991.

  • J. Svenningsson.

Shortcut fusion for accumulating parameters & zip-like functions. In International Conference on Functional Programming, Proceedings, pages 124–132. ACM Press, 2002.

22

slide-69
SLIDE 69

References III

  • J. Voigtl¨

ander. Asymptotic improvement of computations over free monads. In Mathematics of Program Construction, Proceedings, volume 5133 of LNCS, pages 388–403. Springer-Verlag, 2008.

  • J. Voigtl¨

ander. Semantics and pragmatics of new shortcut fusion rules. In Functional and Logic Programming, Proceedings, volume 4989 of LNCS, pages 163–179. Springer-Verlag, 2008.

  • P. Wadler.

Theorems for free! In Functional Programming Languages and Computer Architecture, Proceedings, pages 347–359. ACM Press, 1989.

23