Successfully reported this slideshow.
lazy evaluation
hey, i’m fronx.

berlin compiler meetup, feb 2014
infinite lists

graph reduction
bottom
normal order

redex
call by need

constant subexpression

strictness in
an argument
...
not
- user-code performance optimization
- how and why to avoid capture
- supercombinators / λ-lifting
- representation in...
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/...
strict
expressions can not

have a value

even if
some of their
subexpressions

do not
http://www.haskell.org/haskellwiki/...
strict
expressions can not

have a value

even if
some of their
subexpressions

do not … have a value
http://www.haskell.o...
“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...
how is this useful?
infinite lists are awesome.
nat :: [Int]
nat = nat' 1
where nat' n = n : nat' (n + 1)
!

take 5 (map sqr nat) == [1,4,9,16,...
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
undefined (throws error)
take 0 _ = []
take n (x : xs) = x : take (n - 1) xs
take n [] = []
!

take 2 (1:1:1:undefined)
== take 2 (1:1:undefined)
== ...
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 defined

=> 1 : 1 : 1 : ⊥
=> 1 : 1 : 1...
strict / non-strict
functions
a function is strict iff

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
(“l...
repeat n = n : repeat n
!

repeat ⊥ = ⊥ : repeat ⊥
repeat n = n : repeat n
!

repeat ⊥ = ⊥ : repeat ⊥

strict
one x = 1
one ⊥ = 1

non-strict
evaluation
strategies
first x y = x

lazy

eager
first 1 (loop 2)

first 1 (loop 2)

=>

=>
first x y = x

eager

lazy

first 1 (loop 2)

first 1 (loop 2)

=> first 1 (2 + (loop 2))

=1

=> first 1 (2 + (2 + (loop 2)))
...
first x y = x

lazy

eager
first 1 (loop 2)

first 1 (loop 2)

=> first 1 (2 + (loop 2))

=1

=> first 1 (2 + (2 + (loop 2)))
=...
first x y = x

lazy

eager
first (loop 1) 2

first (loop 1) 2

=> first (1 + (loop 1)) 2

=> loop 1

=> first (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 + ...
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 + ...
weak head normal form
expression head is one of:
-

variable
data object
built-in function
lambda abstraction

http://rese...
weak head normal form
An expression has
no top-level redex
iff
it is in
weak head normal form.

http://research.microsoft.c...
weak head normal form
examples:
3
1 : (2 : …) == CONS 1 (CONS 2 …)
+ (- 4 3)
(λx. + 5 1)

http://research.microsoft.com/en...
weak head normal form
result:
Ignore inner redexes
as long as you can.

http://research.microsoft.com/en-us/um/people/simo...
graph reduction
a way to model / implement
lazy evaluation
graph reduction
first = λ x y . x
first = λ x . λ y . x
first 1 ⊥

@
@
λx
λy
x

⊥
1
graph reduction
first = λ x y . x
first = λ x . λ y . x
first 1 ⊥
leftmost outermost
reduction
=
normal-order
reduction

@
@
...
graph reduction
first = λ x y . x
first = λ x . λ y . x
first 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.micr...
maximal free expression
a free expression
which is not a subexpression
of another free expression

http://research.microso...
full laziness
λy. + y (sqrt 4)

@
λx

λy $

“x(1), x(2)”

@

@
+

y

maximal free
expression in $

@
sqrt

4

free subexpr...
full laziness
λy. + y (sqrt 4)

@
λx

λy

“x(1), x(2)”

@

@
+

y

sqrt4

@
sqrt

4

Extract all the
maximal free
expressi...
full laziness
fully lazy λ-lifting SPJ87
extract MFEs via closures Sestoft97
sharing via labelling Blanc/Levy/Maranget07
v...
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
su...
product-matching
= zeroPair (x,y) = 0
!

= Eval [[ zeroPair ]] ⊥ = ⊥

strict product-matching

= Eval [[ zeroPair ]] ⊥ = 0...
lazy product-matching
= zeroPair (x,y) = 0
!

= Eval [[ zeroPair ]] ⊥
= Eval [[ λ(Pair x y). 0 ]] ⊥
= Eval [[ λx. λy. 0 ]]...
lazy product-matching
SEL-PAIR-1 (Pair x y) = x
SEL-PAIR-1 ⊥

=⊥

SEL-PAIR-2 (Pair x y) = y
SEL-PAIR-2 ⊥

=⊥

http://resea...
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...
summary
- f is strict

f⊥=⊥

- graph reduction
- sharing
- lazy pattern-matching
- go and read those papers/books
okay.
that’s it for today.
“Laziness kept us pure.”
Simon Peyton Jones

http://www.techworld.com.au/article/261007/a-z_programming_languages_haskell/...
“If your program is slow, don't bother
profiling. Just scatter bang patterns
throughout your code like confetti.
They're ma...
Lazy evaluation
Upcoming SlideShare
Loading in …5
×

Lazy evaluation

855 views

Published on

Published in: Technology, Business
  • Be the first to comment

Lazy evaluation

  1. 1. lazy evaluation hey, i’m fronx. berlin compiler meetup, feb 2014
  2. 2. infinite 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
  3. 3. not - user-code performance optimization - how and why to avoid capture - supercombinators / λ-lifting - representation in memory - garbage collection - compiler optimizations
  4. 4. http://research.microsoft.com/en-us/um/people/simonpj/papers/slpj-book-1987/
  5. 5. semantics strict non-strict vs. evaluation strategy eager lazy
  6. 6. as a language property
  7. 7. non-strict expressions can have a value even if some of their subexpressions do not http://www.haskell.org/haskellwiki/Non-strict_semantics
  8. 8. strict expressions can not have a value even if some of their subexpressions do not http://www.haskell.org/haskellwiki/Non-strict_semantics
  9. 9. 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
  10. 10. “not have a value”?
  11. 11. loop :: Int -> Int loop n = 1 + loop n
  12. 12. 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,…
  13. 13. how is this useful?
  14. 14. infinite 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]
  15. 15. http://mybroadband.co.za/news/wp-content/uploads/2013/03/Barack-Obama-Michelle-Obama-not-bad.jpg
  16. 16. ⊥ ”bottom” “a computation which never completes successfully” http://www.haskell.org/haskellwiki/Bottom
  17. 17. ⊥ bottom :: a bottom = bottom undefined (throws error)
  18. 18. take 0 _ = [] take n (x : xs) = x : take (n - 1) xs take n [] = [] ! take 2 (1:1:1:undefined) == take 2 (1:1:undefined) == [1,1]
  19. 19. repeat n = n : repeat n ! repeat 1 => 1 : ⊥ => 1 : 1 : ⊥ => 1 : 1 : 1 : ⊥ => 1 : 1 : 1 : 1 : ⊥ …
  20. 20. repeat n = n : repeat n ! repeat 1 => 1 : ⊥ => 1 : 1 : ⊥ Terms approximation, more defined => 1 : 1 : 1 : ⊥ => 1 : 1 : 1 : 1 : ⊥ … http://en.wikibooks.org/wiki/Haskell/Denotational_semantics
  21. 21. strict / non-strict functions
  22. 22. a function is strict iff f⊥=⊥
  23. 23. strictness of functions id = λ x . x (λx.x)⊥=⊥ strict
  24. 24. strictness of functions one = λ x . 1 (λx.1)⊥=1 non-strict
  25. 25. strictness of functions second = λ x y . y (λxy.y)⊥ 2=2 strict in its 2nd argument non-strict in its 1st argument
  26. 26. 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 : ⊥ …
  27. 27. repeat n = n : repeat n ! repeat ⊥ = ⊥ : repeat ⊥
  28. 28. repeat n = n : repeat n ! repeat ⊥ = ⊥ : repeat ⊥ strict
  29. 29. one x = 1 one ⊥ = 1 non-strict
  30. 30. evaluation strategies
  31. 31. first x y = x lazy eager first 1 (loop 2) first 1 (loop 2) => =>
  32. 32. first x y = x eager lazy first 1 (loop 2) first 1 (loop 2) => first 1 (2 + (loop 2)) =1 => first 1 (2 + (2 + (loop 2))) = ⊥
  33. 33. first x y = x lazy eager first 1 (loop 2) first 1 (loop 2) => first 1 (2 + (loop 2)) =1 => first 1 (2 + (2 + (loop 2))) = ⊥ redex: reducible expression
  34. 34. first x y = x lazy eager first (loop 1) 2 first (loop 1) 2 => first (1 + (loop 1)) 2 => loop 1 => first (1 + (1 + (loop 1))) 2 => 1 + (loop 1) = ⊥ => 1 + (1 + (loop 1)) = ⊥
  35. 35. nat n = n : nat (n + 1) lazy eager nat 1 nat 1 => =>
  36. 36. 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.
  37. 37. 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 define the point where it has to stop?
  38. 38. 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/
  39. 39. weak head normal form An expression has no top-level redex iff it is in weak head normal form. http://research.microsoft.com/en-us/um/people/simonpj/papers/slpj-book-1987/
  40. 40. 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/
  41. 41. 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/
  42. 42. graph reduction a way to model / implement lazy evaluation
  43. 43. graph reduction first = λ x y . x first = λ x . λ y . x first 1 ⊥ @ @ λx λy x ⊥ 1
  44. 44. graph reduction first = λ x y . x first = λ x . λ y . x first 1 ⊥ leftmost outermost reduction = normal-order reduction @ @ λx λy x ⊥ 1
  45. 45. graph reduction first = λ x y . x first = λ x . λ y . x first 1 ⊥ instantiate the lambda body @ @ λx λy x ⊥ 1 @ λy 1 ⊥ 1
  46. 46. graph reduction sqr = λ x . x * x sqr 2 @ 2 λx @ @ @ * @ x x * 2 2 4
  47. 47. graph reduction sqr (6 + 1) @ @ λx @ @ @ * x x + 6 1
  48. 48. graph reduction sqr (6 + 1) call by name @ @ λx @ @ @ * @ x 1 @ @ @ + 6 * x @ + + @ 1 6 1 6 …
  49. 49. graph reduction sqr (6 + 1) sharing call by need @ @ λx @ @ @ * x x + 6 @ 1 @ * @ @ 1 + 6 @ @ * 7 49
  50. 50. + call by name + sharing + —————— + call by need
  51. 51. shadowing (λx.λx.x)1 2 @ 2 @ λx λx x 1 @ λx x 2 2
  52. 52. 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/
  53. 53. 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/
  54. 54. 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/
  55. 55. 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/
  56. 56. full laziness fully lazy λ-lifting SPJ87 extract MFEs via closures Sestoft97 sharing via labelling Blanc/Levy/Maranget07 variants (sorry, no time for details.) A Unified Approach to Fully Lazy Sharing, Balabonski 2012
  57. 57. so how does take work? take 0 _ = [] take n (x : xs) = x : take (n - 1) xs take n [] = []
  58. 58. 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
  59. 59. 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/
  60. 60. 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/
  61. 61. 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/
  62. 62. 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/
  63. 63. summary - f is strict f⊥=⊥ - graph reduction - sharing - lazy pattern-matching - go and read those papers/books
  64. 64. okay. that’s it for today.
  65. 65. “Laziness kept us pure.” Simon Peyton Jones http://www.techworld.com.au/article/261007/a-z_programming_languages_haskell/?pp=7
  66. 66. “If your program is slow, don't bother profiling. Just scatter bang patterns throughout your code like confetti. They're magic!” https://twitter.com/evilhaskelltips/status/429788191613140992

×