# lazy evaluation

Post on 29-Aug-2014

401 views

Embed Size (px)

DESCRIPTION

TRANSCRIPT

- lazy evaluation hey, im fronx. berlin compiler meetup, feb 2014
- innite lists graph reduction bottom normal order redex call by need constant subexpression strictness in an argument sharing leftmost outermost full laziness approximation eager instantiation WHNF thunk
- not - user-code performance optimization - how and why to avoid capture - supercombinators / -lifting - representation in memory - garbage collection - compiler optimizations
- http://research.microsoft.com/en-us/um/people/simonpj/papers/slpj-book-1987/
- semantics strict non-strict vs. evaluation strategy eager lazy
- as a language property
- non-strict expressions can have a value even if some of their subexpressions do not http://www.haskell.org/haskellwiki/Non-strict_semantics
- strict expressions can not have a value even if some of their subexpressions do not http://www.haskell.org/haskellwiki/Non-strict_semantics
- strict expressions can not have a value even if some of their subexpressions do not have a value http://www.haskell.org/haskellwiki/Non-strict_semantics
- not have a value?
- loop :: Int -> Int loop n = 1 + loop n
- loop :: Int -> Int loop n = 1 + loop n repeat :: Int -> [Int] repeat n = n : repeat n ! > repeat 1 [1,1,1,1,1,1,1,1,1,1,1,1,
- how is this useful?
- innite lists are awesome. nat :: [Int] nat = nat' 1 where nat' n = n : nat' (n + 1) ! take 5 (map sqr nat) == [1,4,9,16,25]
- http://mybroadband.co.za/news/wp-content/uploads/2013/03/Barack-Obama-Michelle-Obama-not-bad.jpg
- bottom a computation which never completes successfully http://www.haskell.org/haskellwiki/Bottom
- bottom :: a bottom = bottom undened (throws error)
- take 0 _ = [] take n (x : xs) = x : take (n - 1) xs take n [] = [] ! take 2 (1:1:1:undened) == take 2 (1:1:undened) == [1,1]
- repeat n = n : repeat n ! repeat 1 => 1 : => 1 : 1 : => 1 : 1 : 1 : => 1 : 1 : 1 : 1 :
- repeat n = n : repeat n ! repeat 1 => 1 : => 1 : 1 : Terms approximation, more dened => 1 : 1 : 1 : => 1 : 1 : 1 : 1 : http://en.wikibooks.org/wiki/Haskell/Denotational_semantics
- strict / non-strict functions
- a function is strict i f=
- strictness of functions id = x . x (x.x)= strict
- strictness of functions one = x . 1 (x.1)=1 non-strict
- strictness of functions second = x y . y (xy.y) 2=2 strict in its 2nd argument non-strict in its 1st argument
- repeat n = n : repeat n Question: ! repeat 1 => 1 : => 1 : 1 : => 1 : 1 : 1 : Is repeat strict or non-strict (lazy)? => 1 : 1 : 1 : 1 :
- repeat n = n : repeat n ! repeat = : repeat
- repeat n = n : repeat n ! repeat = : repeat strict
- one x = 1 one = 1 non-strict
- evaluation strategies
- rst x y = x lazy eager rst 1 (loop 2) rst 1 (loop 2) => =>
- rst x y = x eager lazy rst 1 (loop 2) rst 1 (loop 2) => rst 1 (2 + (loop 2)) =1 => rst 1 (2 + (2 + (loop 2))) =
- rst x y = x lazy eager rst 1 (loop 2) rst 1 (loop 2) => rst 1 (2 + (loop 2)) =1 => rst 1 (2 + (2 + (loop 2))) = redex: reducible expression
- rst x y = x lazy eager rst (loop 1) 2 rst (loop 1) 2 => rst (1 + (loop 1)) 2 => loop 1 => rst (1 + (1 + (loop 1))) 2 => 1 + (loop 1) = => 1 + (1 + (loop 1)) =
- nat n = n : nat (n + 1) lazy eager nat 1 nat 1 => =>
- nat n = n : nat (n + 1) eager lazy nat 1 nat 1 => 1 : nat (1+1) = 1 : nat (1 + 1) => 1 : nat 2 => 1 : 2 : nat (2 + 1) = the function is still strict! lazy evaluation allows you to look at intermediate results, though.
- nat n = n : nat (n + 1) eager lazy nat 1 nat 1 => 1 : nat (1+1) = 1 : nat (1 + 1) => 1 : nat 2 => 1 : 2 : nat (2 + 1) = Question: How do you dene the point where it has to stop?
- weak head normal form expression head is one of: - variable data object built-in function lambda abstraction http://research.microsoft.com/en-us/um/people/simonpj/papers/slpj-book-1987/
- weak head normal form An expression has no top-level redex i it is in weak head normal form. http://research.microsoft.com/en-us/um/people/simonpj/papers/slpj-book-1987/
- weak head normal form examples: 3 1 : (2 : ) == CONS 1 (CONS 2 ) + (- 4 3) (x. + 5 1) http://research.microsoft.com/en-us/um/people/simonpj/papers/slpj-book-1987/
- weak head normal form result: Ignore inner redexes as long as you can. http://research.microsoft.com/en-us/um/people/simonpj/papers/slpj-book-1987/
- graph reduction a way to model / implement lazy evaluation
- graph reduction rst = x y . x rst = x . y . x rst 1 @ @ x y x 1
- graph reduction rst = x y . x rst = x . y . x rst 1 leftmost outermost reduction = normal-order reduction @ @ x y x 1
- graph reduction rst = x y . x rst = x . y . x rst 1 instantiate the lambda body @ @ x y x 1 @ y 1 1
- graph reduction sqr = x . x * x sqr 2 @ 2 x @ @ @ * @ x x * 2 2 4
- graph reduction sqr (6 + 1) @ @ x @ @ @ * x x + 6 1
- graph reduction sqr (6 + 1) call by name @ @ x @ @ @ * @ x 1 @ @ @ + 6 * x @ + + @ 1 6 1 6
- graph reduction sqr (6 + 1) sharing call by need @ @ x @ @ @ * x x + 6 @ 1 @ * @ @ 1 + 6 @ @ * 7 49
- + call by name + sharing + + call by need
- shadowing (x.x.x)1 2 @ 2 @ x x x 1 @ x x 2 2
- full laziness y. + y (sqrt 4) @ x y x(1), x(2) @ @ + constant subexpression y @ sqrt 4 http://research.microsoft.com/en-us/um/people/simonpj/papers/slpj-book-1987/
- maximal free expression a free expression which is not a subexpression of another free expression http://research.microsoft.com/en-us/um/people/simonpj/papers/slpj-book-1987/
- full laziness y. + y (sqrt 4) @ x y $ x(1), x(2) @ @ + y maximal free expression in $ @ sqrt 4 free subexpression http://research.microsoft.com/en-us/um/people/simonpj/papers/slpj-book-1987/
- full laziness y. + y (sqrt 4) @ x y x(1), x(2) @ @ + y sqrt4 @ sqrt 4 Extract all the maximal free expressions! ! |o/ http://research.microsoft.com/en-us/um/people/simonpj/papers/slpj-book-1987/
- full laziness fully lazy -lifting SPJ87 extract MFEs via closures Sestoft97 sharing via labelling Blanc/Levy/Maranget07 variants (sorry, no time for details.) A Unied Approach to Fully Lazy Sharing, Balabonski 2012
- so how does take work? take 0 _ = [] take n (x : xs) = x : take (n - 1) xs take n [] = []
- so how does take work? take 0 _ = [] take n (x : xs) = x : take (n - 1) xs take n [] = [] patterns - variable constant sum constructor product constructor
- product-matching = zeroPair (x,y) = 0 ! = Eval [[ zeroPair ]] = strict product-matching = Eval [[ zeroPair ]] = 0 lazy product-matching http://research.microsoft.com/en-us/um/people/simonpj/papers/slpj-book-1987/
- lazy product-matching = zeroPair (x,y) = 0 ! = Eval [[ zeroPair ]] = Eval [[ (Pair x y). 0 ]] = Eval [[ x. y. 0 ]] (SEL-PAIR-1 ) (SEL-PAIR-2 ) = Eval [[ y. 0 ]] (SEL-PAIR-2 ) =0 http://research.microsoft.com/en-us/um/people/simonpj/papers/slpj-book-1987/
- lazy product-matching SEL-PAIR-1 (Pair x y) = x SEL-PAIR-1 = SEL-PAIR-2 (Pair x y) = y SEL-PAIR-2 = http://research.microsoft.com/en-us/um/people/simonpj/papers/slpj-book-1987/
- lazy product-matching SEL-PAIR-1 (Pair x y) = x SEL-PAIR-1 = SEL-PAIR-2 (Pair x y) = y SEL-PAIR-2 = SEL-constr-i (constr a1 ai an) = ai SEL-constr-i = http://research.microsoft.com/en-us/um/people/simonpj/papers/slpj-book-1987/
- summary - f is strict f= - graph reduction - sharing - lazy pattern-matching - go and read those papers/books
- okay. thats it for today.
- Laziness kept us pure. Simon Peyton Jones http://www.techworld.com.au/article/261007/a-z_programming_languages_haskell/?pp=7
- If your program is slow, don't bother proling. Just scatter bang patterns throughout your code like confetti. They're magic! https://twitter.com/evilhaskelltips/status/429788191613140992