Lazy Evaluation CSCE 314: Programming Languages Dr. Dylan Shell

Slides:



Advertisements
Similar presentations
Chapter 5: Abstraction, parameterization, and qualification Xinming (Simon) Ou CIS 505: Programming Languages Kansas State University Fall
Advertisements

The lambda calculus David Walker CS 441. the (untyped) lambda calculus a language of functions e ::= x | \x.e | e1 e2 v ::= \x.e there are several different.
Six compound procedures and higher-order procedures.
Starting Out with C++: Early Objects 5/e © 2006 Pearson Education. All Rights Reserved Starting Out with C++: Early Objects 5 th Edition Chapter 5 Looping.
Copyright © 2006 The McGraw-Hill Companies, Inc. Programming Languages 2nd edition Tucker and Noonan Chapter 14 Functional Programming It is better to.
UNIVERSITY OF SOUTH CAROLINA Department of Computer Science and Engineering CSCE 330 Programming Language Structures Haskell Fall 2005 Marco Valtorta
CSC321: Programming Languages14-1 Programming Languages Tucker and Noonan Chapter 14: Functional Programming 14.1 Functions and the Lambda Calculus 14.2.
Chapter 14 Programming With Streams. Streams  A stream is an infinite sequence of values.  We could define a special data type for them: data Stream.
Comp 205: Comparative Programming Languages Lazy Evaluation Errors Evaluation Strategies Infinite Lists…. Lecture notes, exercises, etc., can be found.
Haskell Chapter 1, Part I. Highly Recommended  Learn you a Haskell for Great Good. Miran Lipovaca.
Functional Programming Universitatea Politehnica Bucuresti Adina Magda Florea
CSC 580 – Theory of Programming Languages, Spring, 2009 Week 9: Functional Languages ML and Haskell, Dr. Dale E. Parson.
CSC 107 – Programming For Science. Announcements  Memorization is not important, but…  … you will all still be responsible for information  Instead.
Functional Programming With examples in F#. Pure Functional Programming Functional programming involves evaluating expressions rather than executing commands.
11/1/20151 GC16/3011 Functional Programming Lecture 5 Miranda patterns, functions, recursion and lists.
CSC 107 – Programming For Science. The Week’s Goal.
Lee CSCE 314 TAMU 1 CSCE 314 Programming Languages Haskell 101 Dr. Hyunyoung Lee.
1 do-while Statement 2 Do-While Statement Is a looping control structure in which the loop condition is tested after each iteration of the loop. SYNTAX.
Lee CSCE 314 TAMU 1 CSCE 314 Programming Languages Haskell: More on Functions and List Comprehensions Dr. Hyunyoung Lee.
CS April 2002 Lazy Evaluation, Thunks, and Streams.
CSE 5317/4305 L12: Higher-Order Functions1 Functional Languages and Higher-Order Functions Leonidas Fegaras.
Alternate Version of STARTING OUT WITH C++ 4 th Edition Chapter 5 Looping.
Haskell Basics CSCE 314 Spring CSCE 314 – Programming Studio Using GHC and GHCi Log in to unix.cse.tamu.edu (or some other server) From a shell.
Haskell Introduction CSCE 314 Spring CSCE 314 – Programming Studio Historical Background 1930s: Alonzo Church develops the lambda calculus, a simple.
Haskell Chapter 5, Part II. Topics  Review/More Higher Order Functions  Lambda functions  Folds.
Today… Python Keywords. Iteration (or “Loops”!) Winter 2016CISC101 - Prof. McLeod1.
1 PROGRAMMING IN HASKELL An Introduction Based on lecture notes by Graham Hutton The book “Learn You a Haskell for Great Good” (and a few other sources)
Functional Programming
CS314 – Section 5 Recitation 9
Recursion.
Simplifying Expressions
CSE341: Programming Languages Lecture 14 Thunks, Laziness, Streams, Memoization Dan Grossman Spring 2017.
2 Chapter Chapter 2 Integers and Introduction to Variables.
6.001 SICP Variations on a Scheme
6.3 Solving Systems of Linear Equations in Three Variables
More on Lambda Calculus
Haskell.
Debugging Haskell by Observing Intermediate Data Structures
CSE341: Programming Languages Lecture 14 Thunks, Laziness, Streams, Memoization Dan Grossman Winter 2013.
Closures and Streams cs784(Prasad) L11Clos
Chapter 5: Looping Starting Out with C++ Early Objects Seventh Edition
Lecture 07 More Repetition Richard Gesick.
CSE341: Programming Languages Lecture 14 Thunks, Laziness, Streams, Memoization Zach Tatlock Winter 2018.
Main Points of Haskell Functional programming Laziness
LESSON 11 – WHILE LOOPS UNIT 5 – 1/10/17.
CSE341: Programming Languages Lecture 14 Thunks, Laziness, Streams, Memoization Dan Grossman Spring 2013.
Functional Programming
Streams Sections 3.5.1,3.5.2 Pages
Alternate Version of STARTING OUT WITH C++ 4th Edition
Programming Languages and Compilers (CS 421)
CSE341: Programming Languages Lecture 14 Thunks, Laziness, Streams, Memoization Dan Grossman Spring 2016.
Dynamic Scoping Lazy Evaluation
CSE341: Programming Languages Lecture 14 Thunks, Laziness, Streams, Memoization Dan Grossman Autumn 2017.
6.001 SICP Environment model
Adding and Subtracting Radicals
CSE341: Programming Languages Lecture 14 Thunks, Laziness, Streams, Memoization Dan Grossman Autumn 2018.
6.001 SICP Streams – the lazy way
6.001 SICP Further Variations on a Scheme
CSCE 314: Programming Languages Dr. Dylan Shell
Computing Fundamentals
Dan Grossman / Eric Mullen Autumn 2017
CSCE 314: Programming Languages Dr. Dylan Shell
6.001 SICP Environment model
Introduction to Programming
CSCE 314: Programming Languages Dr. Dylan Shell
Rehearsal: Lazy Evaluation Infinite Streams in our lazy evaluator
More Scheme CS 331.
Lecture 3 More on Flow Control, More on Functions,
Brett Wortzman Summer 2019 Slides originally created by Dan Grossman
CSE341: Programming Languages Lecture 14 Thunks, Laziness, Streams, Memoization Dan Grossman Spring 2019.
Presentation transcript:

Lazy Evaluation CSCE 314: Programming Languages Dr. Dylan Shell http://science-all.com/images/chestnut/chestnut-06.jpg

Evaluating Functions Consider: add x y = x + y; square x = x * x add (square 2) (add 2 3)

−− apply square: add (2 * 2) (add 2 3) −− apply ∗ : add 4 (add 2 3) add x y = x + y; square x = x * x add (square 2) (add 2 3) −− apply square: add (2 * 2) (add 2 3) −− apply ∗ : add 4 (add 2 3) −− apply inner add : add 4 (2 + 3) −− apply + : add 4 5 −− apply add 4+5 −− apply + 9 −− apply add: (square 2) + (add 2 3) −− apply inner add : (square 2) + (2 + 3) −− apply inner + : (square 2) + 5 −− apply square: (2 * 2) + 5 −− apply * 4+5 −− apply + 9

There are many possible orders to evaluate a function head (1:(reverse [2,3,4,5])) head (1:(reverse [2,3,4,5])) −− apply reverse −− apply head −− ... many steps omitted here 1 head (1 : [5,4,3,2]) −− apply head 1 In Haskell, any two different ways of evaluating the same expression will produce the same final value if they terminate.

There are many possible orders to evaluate a function head (1:(reverse [2,3,4,5])) head (1:(reverse [2,3,4,5])) −− apply reverse −− apply head −− ... many steps omitted here 1 head (1 : [5,4,3,2]) −− apply head 1 In Haskell, any two different ways of evaluating the same expression will produce the same final value if they terminate. The same isn’t true of imperative programing languages.

Two styles: Strict Evaluation Eager, call-by-value evaluation. In C/C++/Java a call such as: f(btho(whom_ever),increment_count()) we know that whom_ever will be beaten, then the global variable will be updated. This is leftmost, innermost evaluation. It would be very confusing if we couldn’t count on those being evaluated! Eager, call-by-value evaluation. Lazy Evaluation In Haskell an expression: fst (5, (factorial 10000)) the second, expensive computation won’t even be performed. Outermost evaluation, only when needed. Some optimizations (via memoization): foo (factorial 10) “meh” (factorial 10) Call-by-name evaluation.

Two styles: Strict Evaluation Eager, call-by-value evaluation. In C/C++/Java a call such as: f(btho(whom_ever),increment_count()) we know that whom_ever will be beaten, then the global variable will be updated. This is leftmost, innermost evaluation. It would be very confusing if we couldn’t count on those being evaluated! Eager, call-by-value evaluation. Lazy Evaluation In Haskell an expression: fst (5, (factorial 10000)) the second, expensive computation won’t even be performed. Outermost evaluation, only when needed. Some optimizations (via memoization): foo (factorial 10) “meh” (factorial 10) Call-by-name evaluation. In C/C++/Java have you ever thought about what happens when first_cond() returns true in: if (first_cond() || second_cond()) { … } or: if ((!first_cond()) && second_cond()) { Compare to: True ∧ True = True _ ∧ _ = False

Haskell’s call-by-name evaluation What about lambda expressions: *Main> (\x -> 3 * 2 + x) (4+2) 12 It looks like the following are possible evaluations: Haskell will not simplify inside lambda expression (i.e., reducing as on the example on the right) because the lambda’s are treated as black boxes. A lambda’s only simplification operation is to apply it. (\x -> 3 * 2 + x) (4+2) 3 * 2 + (4+2) 3 * 2 + 6 6 + 6 12 (\x -> 3 * 2 + x) (4+2) (\x -> 3 * 2 + x) 6 3 * 2 + 6 6 + 6 12 (\x -> 3 * 2 + x) (4+2) (\x -> 6 + x) (4+2) 6 + (4+2) 6 + 6 12

Eager, call-by-value evaluation. Lazy Evaluation Strict Evaluation Eager, call-by-value evaluation. May fail to halt working on some computation that is later discarded. May use fewer evaluations when it does halt. Lazy Evaluation Call-by-name evaluation. Can halt even on infinite structures. But care is needed cf. 3 `elem` [2,4..] May need more evaluations, but saving intermediate results helps mitigate these costs. Haskell has the $! operator to force strict evaluation; this can be helpful to save stack space.

Eager, call-by-value evaluation. Lazy Evaluation Strict Evaluation Eager, call-by-value evaluation. May fail to halt working on some computation that is later discarded. May use fewer evaluations when it does halt. Lazy Evaluation Call-by-name evaluation. Can halt even on infinite structures. But care is needed cf. 3 `elem` [2,4..] May need more evaluations, but saving intermediate results helps mitigate these costs. Haskell has the $! operator to force strict evaluation; this can be helpful to save stack space. Examples: let g x y = y g 2 4 4 g (2 `div` 0) 10 10 (g $! (2 `div` 0)) 10 *** Exception: divide by zero Note that these three uses force strictness in different ways: (g $! x) y (g x) $! y (g $! x) $! y

Eager, call-by-value evaluation. Lazy Evaluation Strict Evaluation Eager, call-by-value evaluation. May fail to halt working on some computation that is later discarded. May use fewer evaluations when it does halt. Lazy Evaluation Call-by-name evaluation. Can halt even on infinite structures. But care is needed cf. 3 `elem` [2,4..] May need more evaluations, but saving intermediate results helps mitigate these costs. Haskell has the $! operator to force strict evaluation; this can be helpful to save stack space. This operator is defined in terms of seq: ($!) :: (a -> b) -> a -> b f $! x = x `seq` f x