Evaluation Strategies Call-me-maybe Moritz Flucht Institute for - - PowerPoint PPT Presentation

evaluation strategies
SMART_READER_LITE
LIVE PREVIEW

Evaluation Strategies Call-me-maybe Moritz Flucht Institute for - - PowerPoint PPT Presentation

Evaluation Strategies Call-me-maybe Moritz Flucht Institute for Software Engineering and Programming Languages Universitt zu Lbeck December 7th, 2015 Concepts of Programming Languages Introduction Taxonomy Lazy evaluation Eager


slide-1
SLIDE 1

Evaluation Strategies

Call-me-maybe Moritz Flucht

Institute for Software Engineering and Programming Languages Universität zu Lübeck

December 7th, 2015 Concepts of Programming Languages

slide-2
SLIDE 2

Introduction Taxonomy Lazy evaluation Eager evaluation Optimistic evaluation Conclusion

Motivation

“At a conference on programming languages you might hear someone say, ‘The normal-order language Hassle has certain strict

  • primitives. Other procedures take their arguments by lazy

evaluation.’”

— H. Abelson, The Structure and Interpretation of Computer Programs

  • M. Flucht (Universität zu Lübeck)

Evaluation Strategies 1/14

slide-3
SLIDE 3

Introduction Taxonomy Lazy evaluation Eager evaluation Optimistic evaluation Conclusion

Contents

1

Taxonomy Applicative vs. normal-order Strictness vs. non-strictness

2

Lazy evaluation Call-by-name vs. call-by-need Benefjts and drawbacks Implementation

3

Eager evaluation Call-by-value vs. call-by-sharing Lazy features in applicative-order languages

4

Optimistic evaluation Idea Implementation & components

  • M. Flucht (Universität zu Lübeck)

Evaluation Strategies 3/28

slide-4
SLIDE 4

Introduction Taxonomy Lazy evaluation Eager evaluation Optimistic evaluation Conclusion

Taxonomy

  • M. Flucht (Universität zu Lübeck)

Evaluation Strategies 1/7

slide-5
SLIDE 5

Introduction Taxonomy Lazy evaluation Eager evaluation Optimistic evaluation Conclusion

Semantics vs. Evaluators

Describing programming languages

Applicative-order

All parameters are evaluated before entering the body. Found in traditional languages like C, Java, Ruby.

Normal-order

Parameter evaluation is deferred until they are used. Found in functional languages like Haskell and Miranda.

  • M. Flucht (Universität zu Lübeck)

Evaluation Strategies 5/28

slide-6
SLIDE 6

Introduction Taxonomy Lazy evaluation Eager evaluation Optimistic evaluation Conclusion

Semantics vs. Evaluators

Describing programming languages

Example: try-function in Scheme

Consider

(define (try a b) (if (= a 0) 1 b))

being called with (try 0 (/ 42 0))

  • M. Flucht (Universität zu Lübeck)

Evaluation Strategies 3/14

slide-7
SLIDE 7

Introduction Taxonomy Lazy evaluation Eager evaluation Optimistic evaluation Conclusion

Semantics vs. Evaluators

Describing procedures and parameters

Strictness

A strict parameter is evaluated before the function is applied. Read: a function x is strict in its parameter y.

Non-Strictness

A non-strict parameter is evaluated at fjrst use.

  • M. Flucht (Universität zu Lübeck)

Evaluation Strategies 1/4

slide-8
SLIDE 8

Introduction Taxonomy Lazy evaluation Eager evaluation Optimistic evaluation Conclusion

Semantics vs. Evaluators

Describing evaluators

Eager evaluation

Expressions are evaluated when they are encountered.

Lazy evaluation

Expressions are evaluated when they are needed.

  • M. Flucht (Universität zu Lübeck)

Evaluation Strategies 2/7

slide-9
SLIDE 9

Introduction Taxonomy Lazy evaluation Eager evaluation Optimistic evaluation Conclusion

Lazy evaluation

  • M. Flucht (Universität zu Lübeck)

Evaluation Strategies 9/28

slide-10
SLIDE 10

Introduction Taxonomy Lazy evaluation Eager evaluation Optimistic evaluation Conclusion

Lazy evaluation

Deferring expression evaluation

Class of strategies, not one single technique Delay evaluation to the last possible moment Unused expressions might never be evaluated

Example: unless in lazy Scheme

1

(define (unless condition _then _else)

2

(if condition _else _then))

  • M. Flucht (Universität zu Lübeck)

Evaluation Strategies 5/14

slide-11
SLIDE 11

Introduction Taxonomy Lazy evaluation Eager evaluation Optimistic evaluation Conclusion

Lazy evaluation

Call-by-name vs. call-by-need

Call-by-name

Expressions are evaluated every time their value is needed Similar to macro expansion

Call-by-need

The computed value is stored after fjrst usage Call-by-name with memoization Only practical with immutable values and pure functions

  • M. Flucht (Universität zu Lübeck)

Evaluation Strategies 11/28

slide-12
SLIDE 12

Introduction Taxonomy Lazy evaluation Eager evaluation Optimistic evaluation Conclusion

Lazy evaluation

Why bother?—Advantages of laziness

More concise and intuitive code (have laziness take care of the fallout) Generate-and-fjlter paradigm (intermediate lists) Infjnite data structures

Example: Infjnite lists in Haskell

Consider calling functions like length , sort and doubleList on

1

magic :: Int -> Int -> [Int]

2

magic m n = m : (magic n (m+n))

  • M. Flucht (Universität zu Lübeck)

Evaluation Strategies 3/7

slide-13
SLIDE 13

Introduction Taxonomy Lazy evaluation Eager evaluation Optimistic evaluation Conclusion

Lazy evaluation

Why bother?—Advantages of laziness

  • getIt (magic 1 1) 3
  • getIt (1 : (magic 1 (1+1))) 3
  • getIt (magic 1 (1+1)) (3-1)
  • getIt (1 : (magic (1+1) (1+(1+1)))) (3-1)
  • getIt (1 : (magic (1+1) (1+(1+1)))) 2
  • getIt (magic (1+1) (1+(1+1))) (2-1)
  • getIt (magic 2 (1+2)) (2-1)
  • getIt (2 : magic (1+2) (2+(1+2))) (2-1)
  • getIt (2 : (magic (1+2) (2+(1+2))) 1
  • 2
  • M. Flucht (Universität zu Lübeck)

Evaluation Strategies 13/28 1

getIt :: [Int] -> Int -> Int

2

getIt [] _ = undefined

3

getIt (x:xs) 1 = x

4

getIt (x:xs) n = getIt xs (n-1)

slide-14
SLIDE 14

Introduction Taxonomy Lazy evaluation Eager evaluation Optimistic evaluation Conclusion

Lazy evaluation

Why bother?—Advantages of laziness

  • getIt (magic 1 1) 3
  • getIt (1 : (magic 1 (1+1))) 3
  • getIt (magic 1 (1+1)) (3-1)
  • getIt (1 : (magic (1+1) (1+(1+1)))) (3-1)
  • getIt (1 : (magic (1+1) (1+(1+1)))) 2
  • getIt (magic (1+1) (1+(1+1))) (2-1)
  • getIt (magic 2 (1+2)) (2-1)
  • getIt (2 : magic (1+2) (2+(1+2))) (2-1)
  • getIt (2 : (magic (1+2) (2+(1+2))) 1
  • 2
  • M. Flucht (Universität zu Lübeck)

Evaluation Strategies 13/28 1

getIt :: [Int] -> Int -> Int

2

getIt [] _ = undefined

3

getIt (x:xs) 1 = x

4

getIt (x:xs) n = getIt xs (n-1)

slide-15
SLIDE 15

Introduction Taxonomy Lazy evaluation Eager evaluation Optimistic evaluation Conclusion

Lazy evaluation

Why bother?—Advantages of laziness

  • getIt (magic 1 1) 3
  • getIt (1 : (magic 1 (1+1))) 3
  • getIt (magic 1 (1+1)) (3-1)
  • getIt (1 : (magic (1+1) (1+(1+1)))) (3-1)
  • getIt (1 : (magic (1+1) (1+(1+1)))) 2
  • getIt (magic (1+1) (1+(1+1))) (2-1)
  • getIt (magic 2 (1+2)) (2-1)
  • getIt (2 : magic (1+2) (2+(1+2))) (2-1)
  • getIt (2 : (magic (1+2) (2+(1+2))) 1
  • 2
  • M. Flucht (Universität zu Lübeck)

Evaluation Strategies 13/28 1

getIt :: [Int] -> Int -> Int

2

getIt [] _ = undefined

3

getIt (x:xs) 1 = x

4

getIt (x:xs) n = getIt xs (n-1)

slide-16
SLIDE 16

Introduction Taxonomy Lazy evaluation Eager evaluation Optimistic evaluation Conclusion

Lazy evaluation

Why bother?—Advantages of laziness

  • getIt (magic 1 1) 3
  • getIt (1 : (magic 1 (1+1))) 3
  • getIt (magic 1 (1+1)) (3-1)
  • getIt (1 : (magic (1+1) (1+(1+1)))) (3-1)
  • getIt (1 : (magic (1+1) (1+(1+1)))) 2
  • getIt (magic (1+1) (1+(1+1))) (2-1)
  • getIt (magic 2 (1+2)) (2-1)
  • getIt (2 : magic (1+2) (2+(1+2))) (2-1)
  • getIt (2 : (magic (1+2) (2+(1+2))) 1
  • 2
  • M. Flucht (Universität zu Lübeck)

Evaluation Strategies 13/28 1

getIt :: [Int] -> Int -> Int

2

getIt [] _ = undefined

3

getIt (x:xs) 1 = x

4

getIt (x:xs) n = getIt xs (n-1)

slide-17
SLIDE 17

Introduction Taxonomy Lazy evaluation Eager evaluation Optimistic evaluation Conclusion

Lazy evaluation

Why bother?—Advantages of laziness

  • getIt (magic 1 1) 3
  • getIt (1 : (magic 1 (1+1))) 3
  • getIt (magic 1 (1+1)) (3-1)
  • getIt (1 : (magic (1+1) (1+(1+1)))) (3-1)
  • getIt (1 : (magic (1+1) (1+(1+1)))) 2
  • getIt (1 : (magic (1+1) (1+(1+1)))) 2
  • getIt (magic 2 (1+2)) (2-1)
  • getIt (2 : magic (1+2) (2+(1+2))) (2-1)
  • getIt (2 : (magic (1+2) (2+(1+2))) 1
  • 2
  • M. Flucht (Universität zu Lübeck)

Evaluation Strategies 13/28 1

getIt :: [Int] -> Int -> Int

2

getIt [] _ = undefined

3

getIt (x:xs) 1 = x

4

getIt (x:xs) n = getIt xs (n-1)

slide-18
SLIDE 18

Introduction Taxonomy Lazy evaluation Eager evaluation Optimistic evaluation Conclusion

Lazy evaluation

Why bother?—Advantages of laziness

  • getIt (magic 1 1) 3
  • getIt (1 : (magic 1 (1+1))) 3
  • getIt (magic 1 (1+1)) (3-1)
  • getIt (1 : (magic (1+1) (1+(1+1)))) (3-1)
  • getIt (1 : (magic (1+1) (1+(1+1)))) 2
  • getIt (magic (1+1) (1+(1+1))) (2-1)
  • getIt (magic 2 (1+2)) (2-1)
  • getIt (2 : magic (1+2) (2+(1+2))) (2-1)
  • getIt (2 : (magic (1+2) (2+(1+2))) 1
  • 2
  • M. Flucht (Universität zu Lübeck)

Evaluation Strategies 13/28 1

getIt :: [Int] -> Int -> Int

2

getIt [] _ = undefined

3

getIt (x:xs) 1 = x

4

getIt (x:xs) n = getIt xs (n-1)

slide-19
SLIDE 19

Introduction Taxonomy Lazy evaluation Eager evaluation Optimistic evaluation Conclusion

Lazy evaluation

Why bother?—Advantages of laziness

  • getIt (magic 1 1) 3
  • getIt (1 : (magic 1 (1+1))) 3
  • getIt (magic 1 (1+1)) (3-1)
  • getIt (1 : (magic (1+1) (1+(1+1)))) (3-1)
  • getIt (1 : (magic (1+1) (1+(1+1)))) 2
  • getIt (magic (1+1) (1+(1+1))) (2-1)
  • getIt (magic 2 (1+2)) (2-1)
  • getIt (2 : magic (1+2) (2+(1+2))) (2-1)
  • getIt (2 : (magic (1+2) (2+(1+2))) 1
  • 2
  • M. Flucht (Universität zu Lübeck)

Evaluation Strategies 13/28 1

getIt :: [Int] -> Int -> Int

2

getIt [] _ = undefined

3

getIt (x:xs) 1 = x

4

getIt (x:xs) n = getIt xs (n-1)

slide-20
SLIDE 20

Introduction Taxonomy Lazy evaluation Eager evaluation Optimistic evaluation Conclusion

Lazy evaluation

Why bother?—Advantages of laziness

  • getIt (magic 1 1) 3
  • getIt (1 : (magic 1 (1+1))) 3
  • getIt (magic 1 (1+1)) (3-1)
  • getIt (1 : (magic (1+1) (1+(1+1)))) (3-1)
  • getIt (1 : (magic (1+1) (1+(1+1)))) 2
  • getIt (magic (1+1) (1+(1+1))) (2-1)
  • getIt (magic 2 (1+2)) (2-1)
  • getIt (2 : magic (1+2) (2+(1+2))) (2-1)
  • getIt (2 : (magic (1+2) (2+(1+2))) 1
  • 2
  • M. Flucht (Universität zu Lübeck)

Evaluation Strategies 13/28 1

getIt :: [Int] -> Int -> Int

2

getIt [] _ = undefined

3

getIt (x:xs) 1 = x

4

getIt (x:xs) n = getIt xs (n-1)

slide-21
SLIDE 21

Introduction Taxonomy Lazy evaluation Eager evaluation Optimistic evaluation Conclusion

Lazy evaluation

Why bother?—Advantages of laziness

  • getIt (magic 1 1) 3
  • getIt (1 : (magic 1 (1+1))) 3
  • getIt (magic 1 (1+1)) (3-1)
  • getIt (1 : (magic (1+1) (1+(1+1)))) (3-1)
  • getIt (1 : (magic (1+1) (1+(1+1)))) 2
  • getIt (magic (1+1) (1+(1+1))) (2-1)
  • getIt (magic 2 (1+2)) (2-1)
  • getIt (2 : magic (1+2) (2+(1+2))) (2-1)
  • getIt (2 : (magic (1+2) (2+(1+2))) 1
  • 2
  • M. Flucht (Universität zu Lübeck)

Evaluation Strategies 13/28 1

getIt :: [Int] -> Int -> Int

2

getIt [] _ = undefined

3

getIt (x:xs) 1 = x

4

getIt (x:xs) n = getIt xs (n-1)

slide-22
SLIDE 22

Introduction Taxonomy Lazy evaluation Eager evaluation Optimistic evaluation Conclusion

Lazy evaluation

Why bother?—Advantages of laziness

  • getIt (magic 1 1) 3
  • getIt (1 : (magic 1 (1+1))) 3
  • getIt (magic 1 (1+1)) (3-1)
  • getIt (1 : (magic (1+1) (1+(1+1)))) (3-1)
  • getIt (1 : (magic (1+1) (1+(1+1)))) 2
  • getIt (magic (1+1) (1+(1+1))) (2-1)
  • getIt (magic 2 (1+2)) (2-1)
  • getIt (2 : magic (1+2) (2+(1+2))) (2-1)
  • getIt (2 : (magic (1+2) (2+(1+2))) 1
  • 2
  • M. Flucht (Universität zu Lübeck)

Evaluation Strategies 13/28 1

getIt :: [Int] -> Int -> Int

2

getIt [] _ = undefined

3

getIt (x:xs) 1 = x

4

getIt (x:xs) n = getIt xs (n-1)

slide-23
SLIDE 23

Introduction Taxonomy Lazy evaluation Eager evaluation Optimistic evaluation Conclusion

Lazy evaluation

Implementation: think, thought, thunk

Thunks are allocated to store an unevaluated expression Keep track of evaluation status and the environment Can be forced if a value is needed

Passing to a primitive function Use in a condition Used as an operation

  • M. Flucht (Universität zu Lübeck)

Evaluation Strategies 1/2

slide-24
SLIDE 24

Introduction Taxonomy Lazy evaluation Eager evaluation Optimistic evaluation Conclusion

Lazy evaluation

Implementation: think, thought, thunk

Example: Thunk representations in Python

1

class Thunk:

2

def init (self, expr, env):

3

self._expr = expr

4

self._env = env

5

self._evaluated = False

6

def value(self):

7

if not self._evaluated:

8

self._value = force_eval(self._expr, self._env)

9

self._evaluated = True

10

return self._value

  • M. Flucht (Universität zu Lübeck)

Evaluation Strategies 15/28

slide-25
SLIDE 25

Introduction Taxonomy Lazy evaluation Eager evaluation Optimistic evaluation Conclusion

Lazy evaluation

The downside

Thunk allocation costs and bookkeeping Complicating error handling (order of execution) Impractical for mutable state (“lazy + state = death”) Extensive optimizations necessary

Data and control fmow analysis strictness analysis to determine what is always evaluated cheap eagerness to speculate low cost expressions

  • M. Flucht (Universität zu Lübeck)

Evaluation Strategies 4/7

slide-26
SLIDE 26

Introduction Taxonomy Lazy evaluation Eager evaluation Optimistic evaluation Conclusion

Eager evaluation

  • M. Flucht (Universität zu Lübeck)

Evaluation Strategies 17/28

slide-27
SLIDE 27

Introduction Taxonomy Lazy evaluation Eager evaluation Optimistic evaluation Conclusion

Call-by-value vs. call-by-sharing

“This is a precise description of a fuzzy mechanism.”

Expressions are evaluated before the application of a function.

Call-by-value

Semantic implications for the perception of changes (scope) Creates a copy of a value—usually for primitive types

Call-by-sharing

Maybe technically equivalent to call-by-value Changes to parameters potentially observable Requires mutable values to be distinguished

  • M. Flucht (Universität zu Lübeck)

Evaluation Strategies 9/14

slide-28
SLIDE 28

Introduction Taxonomy Lazy evaluation Eager evaluation Optimistic evaluation Conclusion

Lazy features in applicative-order languages

Special forms are already present (e.g., if-clause) Short circuit evaluation as a compiler optimization Callbacks, promises and futures Call-by-name or call-by-need ofgered for certain value or function

defjnitions on an opt-in basis

  • M. Flucht (Universität zu Lübeck)

Evaluation Strategies 19/28

slide-29
SLIDE 29

Introduction Taxonomy Lazy evaluation Eager evaluation Optimistic evaluation Conclusion

Lazy features in applicative-order languages

Example: Lazy pipelining in JavaScript

Pipelining in JavaScript with lodash was recently patched to behave lazily

1

function ageLt(x) {

2

return function(person) {

3

return person.age < x; };

4

}

5

var people = [

6

{ name: ’Anders’, age: 40 }, { name: ’Binca’, age: 150},

7

{ name: ’Conrad’, age: 200 }, { name: ’Dieta’, age: 70},

8

{ name: ’Finnja’, age: 30 }, { name: ’Geras’, age: 130},

9

{ name: ’Hastig’, age: 20 }, { name: ’Ickey’, age: 200}];

10

var alive = _(people)

11

.filter(ageLt(100)).take(3).value();

  • M. Flucht (Universität zu Lübeck)

Evaluation Strategies 5/7

slide-30
SLIDE 30

Introduction Taxonomy Lazy evaluation Eager evaluation Optimistic evaluation Conclusion

Optimistic evaluation

  • M. Flucht (Universität zu Lübeck)

Evaluation Strategies 3/4

slide-31
SLIDE 31

Introduction Taxonomy Lazy evaluation Eager evaluation Optimistic evaluation Conclusion

The concept of optimistic evaluation

Use on top of already mentioned optimization Many thunks are “always used” or “cheap and usually used” Speculatively evaluate these thunks using call-by-value Abort if the computation takes too long

  • M. Flucht (Universität zu Lübeck)

Evaluation Strategies 11/14

slide-32
SLIDE 32

Introduction Taxonomy Lazy evaluation Eager evaluation Optimistic evaluation Conclusion

Compiler modifjcations

These optimizations are added to the back end of the compiler Code generation for the intermediate language

let expressions

For every let expression let x = <rhs> in <body> we generate a switch

1

if (LET42 != 0) {

2

x = value of <rhs>

3

} else {

4

x = lazy thunk to compute <rhs>

5

when needed

6

} evaluate <body>

  • M. Flucht (Universität zu Lübeck)

Evaluation Strategies 23/28

slide-33
SLIDE 33

Introduction Taxonomy Lazy evaluation Eager evaluation Optimistic evaluation Conclusion

Compiler modifjcations

Abortion

Initially, assume all thunks are sepculated Abort thunks with too long a computation Measured by sample points in an online profjling component

Chunky evaluation

Deal with self-referencing data structures and lists Implemented by means of a recursion counter Switch to lazy evaluation after a given number of speculations

  • M. Flucht (Universität zu Lübeck)

Evaluation Strategies 6/7

slide-34
SLIDE 34

Introduction Taxonomy Lazy evaluation Eager evaluation Optimistic evaluation Conclusion

Compiler modifjcations

Additional things to consider:

Errors in speculated evaluation must not be raised (yet) Unsafe operations have to be excluded from speculation (I/O)

  • M. Flucht (Universität zu Lübeck)

Evaluation Strategies 25/28

slide-35
SLIDE 35

Introduction Taxonomy Lazy evaluation Eager evaluation Optimistic evaluation Conclusion

Compiler modifjcations

Additional things to consider:

Errors in speculated evaluation must not be raised (yet) Unsafe operations have to be excluded from speculation (I/O)

  • M. Flucht (Universität zu Lübeck)

Evaluation Strategies 25/28

slide-36
SLIDE 36

Introduction Taxonomy Lazy evaluation Eager evaluation Optimistic evaluation Conclusion

Run-time component & Results

Switches can be adjusted during run-time Speculations are profjled by means of a heuristic (wastage quotient) Does the potentially wasted work outweigh the cost of thunk allocation? Optimistic evaluation produced a mean speed-up of 15% in test

environment

  • M. Flucht (Universität zu Lübeck)

Evaluation Strategies 13/14

slide-37
SLIDE 37

Introduction Taxonomy Lazy evaluation Eager evaluation Optimistic evaluation Conclusion

Conclusion

  • M. Flucht (Universität zu Lübeck)

Evaluation Strategies 27/28

slide-38
SLIDE 38

Introduction Taxonomy Lazy evaluation Eager evaluation Optimistic evaluation Conclusion

Conclusion

Evaluator Language Procedures & parameters Strategies eager applicative-order strict call-by-value, call-by-sharing lazy normal-order non-strict call-by-name, call-by-need

Optimizations to be made in both eager and lazy Choice dependent on use case, good to have both

  • M. Flucht (Universität zu Lübeck)

Evaluation Strategies 1/1

slide-39
SLIDE 39

Introduction Taxonomy Lazy evaluation Eager evaluation Optimistic evaluation Conclusion

Conclusion

Evaluator Language Procedures & parameters Strategies eager applicative-order strict call-by-value, call-by-sharing lazy normal-order non-strict call-by-name, call-by-need

Optimizations to be made in both eager and lazy Choice dependent on use case, good to have both

  • M. Flucht (Universität zu Lübeck)

Evaluation Strategies 1/1