Download Slides

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts

Closure (computer programming) wikipedia , lookup

C Sharp (programming language) wikipedia , lookup

Lambda calculus wikipedia , lookup

Combinatory logic wikipedia , lookup

Lambda lifting wikipedia , lookup

Lambda calculus definition wikipedia , lookup

Standard ML wikipedia , lookup

Transcript
5
Lazy Evaluation
CSci 4223
●
Principles of Programming Languages
Lecture 25
●
●
Andrew Hirsch
Spring 2013
●
●
●
2
Recall the lambda calculus:
x
Variables
e1 e2
Function application
fn x => e
Anonymous functions
For function application, call-by-value
i.e., when you see e1 e2, then evaluate e2 to a value v2,
●
When e1 = ̯λx. e3, then e1 e2 evaluates to e3[x/v2]
Instead, call-by-name
When e1 = ̯λx. e3, then e1 e2 evaluates to e3[x/e1]
Don't evaluate until you have to!
6
Review
Haskell and Lazy Evaluation
• Functional Semantics: static environment, dynamic
environment, let statements, recursion
• Haskell has lazy evaluation
• Consider the code:
orL :: [Bool] -> Bool
orL = foldr (||) False
• Today:
– Lazy vs Strict Languages
– Thunks
anyL :: (a -> Bool) -> [a] -> Bool
anyL p = orL . map p
five_million :: [Int]
five_million = let f x =
if x <= 5000000
then x : f (x + 1)
else []
in
f 0
3
7
A Small Puzzle
Consider the following SML code:
fun or l = foldr (fn (x, y) => x orelse y) l
fun any p l = or (map p l)
val five_million =
let
fun f x =
if x <= 5,000,000
then x :: f (x + 1)
else []
in
f 0
end
• What is the result of running
> any (fn x => p = ll) five_million
Infinite Lists
ones :: [Int]
ones = 1 : ones
primes :: [Int]
primes = sieve [2 ..]
where
sieve (p : xs) = p : sieve [x | x <- xs,
rem x p /= 0]
●
●
These are infinite lists!
Again, through the power of lazy evaluation
8
Implementing Lazy Evaluation
How do we implement lazy evaluation?
Consider this:
datatype 'a stream =
Empty
| Cons of 'a * (unit -> 'a stream)
exception empty_stream
fun lhead Empty = raise empty_stream
| lhead (Cons (x, xs)) = x
fun ltail Empty = raise empty_stream
| ltail (Cons (x, xs)) = xs ()
9
Five Million Stream
• We can now write five_million as this:
val five_million =
let
fun f x =
if x <= 5000000
then Cons (x, (fn () => f (x + 1)))
else Empty
in
f 0
end
1
0
Memoization
●
How do we keep repeated calculations from being expensive?
triple :: Int → Int
triple = x + x + x
trouble :: Int
trouble = triple expensive_computation
●
●
●
●
Do we really need to calculate expensive_computation
3 times?
Not if it's a pure function!
Just save the result the first time.
Since it's pure, the result won't change,
so there's no issue here.