Laziness By Need Stephen Chang Northeastern University 3/19/2013 - - PowerPoint PPT Presentation

laziness by need
SMART_READER_LITE
LIVE PREVIEW

Laziness By Need Stephen Chang Northeastern University 3/19/2013 - - PowerPoint PPT Presentation

Laziness By Need Stephen Chang Northeastern University 3/19/2013 ESOP 2013, Rome, Italy the most powerful tool for modularization the key to successful programming [Hughes90] Laziness is great. pragmatically important because


slide-1
SLIDE 1

Laziness By Need

Stephen Chang

Northeastern University 3/19/2013 ESOP 2013, Rome, Italy

slide-2
SLIDE 2

Laziness is great.

“pragmatically important because it enables the producer-consumer programming style” [HM76] “the most powerful tool for modularization … the key to successful programming” [Hughes90]

...

Valid?

slide-3
SLIDE 3

Or is it?

“in a lazy language, it’s much more difficult to predict the order of evaluation” [PJ11] “lazy programs can exhibit astonishing poor space behavior” [HHPJW07] “monumentally difficult to reason about time” [Harper11]

slide-4
SLIDE 4

I want the good without the bad.

slide-5
SLIDE 5

Solution: strict + lazy

(when needed)

via static analysis

slide-6
SLIDE 6

“languages should support both strict and lazy” [PJ2011] “The question is: What’s the default? How easy is it to get the other? How do you mix them together?”

Combining lazy and strict has been done?

slide-7
SLIDE 7

Previous Approaches

  • Lenient evaluation: Id, pH

[Nikhil91, NAH+95]

  • Eager Haskell [Maessen02]
  • Optimistic Evaluation [EPJ03]
  • Strictness analysis [Mycroft1981,

BHA86, CPJ85]

  • Cheap Eagerness [Faxen00]

All

Adds strictness to lazy languages.

slide-8
SLIDE 8

How do real-world lazy programmers add strictness?

slide-9
SLIDE 9

seq

slide-10
SLIDE 10

What about adding laziness to strict languages?

“most thunks are unnecessary” [EPJ03] “both before and after

  • ptimization, most

thunks are evaluated” [Faxen00] “most Id90 programs require neither functional nor conditional non-strictness” [SG95] “in our corpus of R programs … the average evaluation rate of promises is 90%” [MHOV12]

slide-11
SLIDE 11

strict languages lazy languages lazy + strictness analysis lazy +

  • ptimistic

evaluation strict + laziness by need

more laziness (placements not exact)

lenient evaluation

slide-12
SLIDE 12

Strict languages already have laziness

slide-13
SLIDE 13

So what’s the problem?

  • Lazy data structures are not enough.
  • Lazy annotations are hard to get right.
  • Laziness is a global property!
slide-14
SLIDE 14

Same Fringe

Two binary trees have the same fringe if they have exactly the same leaves, reading from left to right. samefringe tree1 tree2 = (flatten tree1) == (flatten tree2)

1 2

5,000,001

...

1

5,000,000

...

slide-15
SLIDE 15

Same Fringe

flat (Leaf x) acc = x::acc flat (Node t1 t2) acc = flat t1 (flat t2 acc) flatten t = flat t [] A (Tree X) is either a:

  • Leaf X
  • Node (Tree X) (Tree X)
slide-16
SLIDE 16

Same Fringe (eager)

1 2

5,000,001

...

1

5,000,000

...

let tree1 =

let tree2 =

samefringe tree1 tree2 => false 0m13.363s

slide-17
SLIDE 17

Same Fringe (with streams)

A (Stream X) is either a:

  • Nil
  • Lcons X $(Stream X)
slide-18
SLIDE 18

Same Fringe (with streams)

flatten t = flat t Nil flat (Leaf x) acc = Lcons x $acc flat (Node t1 t2) acc = flat t1 (flat t2 acc)

slide-19
SLIDE 19

Same Fringe (with streams)

streameq $Nil $Nil = true streameq $(Lcons x1 xs1) $(Lcons x2 xs2)= x1==x2 && streameq xs1 xs2 streameq _ _ = false

slide-20
SLIDE 20

Same Fringe (with streams)

samefringe tree1 tree2 => false 0m17.277s samefringe tree1 tree2 = streameq $(flatten tree1) $(flatten tree2) (with lazy trees) 0m36.905s

slide-21
SLIDE 21

Same Fringe (naïvely lazy)

flatten t = flat t Nil flat (Leaf x) acc = Lcons x $acc flat (Node t1 t2) acc = flat t1 (flat t2 acc)

slide-22
SLIDE 22

Same Fringe (properly lazy)

flatten t = flat t Nil flat (Leaf x) acc = Lcons x $acc flat (Node t1 t2) acc = flat t1 $(flat t2 acc)

slide-23
SLIDE 23

Same Fringe (properly lazy)

samefringe tree1 tree2 => false 0m0.002s

slide-24
SLIDE 24

Takeaway

  • Using lazy data structures is not

enough.

  • Additional annotations are needed but

can be tricky.

  • If only there was a tool that could help

with the process . . .

slide-25
SLIDE 25

lcons x y ≡ cons x $y

30s 5s

slide-26
SLIDE 26

Same Fringe (naïvely lazy)

flatten t = flat t Nil flat (Leaf x) acc = Lcons x $acc flat (Node t1 t2) acc = flat t1 (flat t2 acc)

slide-27
SLIDE 27

control flow analysis + laziness flow analysis

slide-28
SLIDE 28

control flow analysis + laziness flow analysis

slide-29
SLIDE 29

arguments that reach a lazy construct arguments that reach a strict context expressions to force

slide-30
SLIDE 30

Transformation

  • Delay all
  • Force all
slide-31
SLIDE 31

Abstract value tracks flow of functions arguments.

slide-32
SLIDE 32

Read: Sets if and only if constraints approximate expression Analysis specified with rules: hold.

slide-33
SLIDE 33
slide-34
SLIDE 34
slide-35
SLIDE 35
slide-36
SLIDE 36

examples: –arguments to primitives –if test expression –function position in an application

strict contexts

contexts where a thunk should not appear

slide-37
SLIDE 37
slide-38
SLIDE 38

We used our tool … … and found some bugs.

slide-39
SLIDE 39

Conclusions

  • Get the benefits of laziness by starting

strict and adding laziness by need.

  • A flow-analysis-based tool can help in

adding laziness to strict programs.

Thanks.