Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Lazy evaluation
(section)
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
== Applications == Delayed evaluation is used particularly in [[functional programming]] languages. When using delayed evaluation, an expression is not evaluated as soon as it gets bound to a variable, but when the evaluator is forced to produce the expression's value. That is, a statement such as <code>x = expression;</code> (i.e. the assignment of the result of an expression to a variable) clearly calls for the expression to be evaluated and the result placed in <code>x</code>, but what actually is in <code>x</code> is irrelevant until there is a need for its value via a reference to <code>x</code> in some later expression whose evaluation could itself be deferred, though eventually the rapidly growing tree of dependencies would be pruned to produce some symbol rather than another for the outside world to see.<ref name="Wadler2006">{{cite conference |last1=Casas |first1=A. |last2=Cabeza |first2=D. |last3=Hermenegildo |first3=M.V. |title=A Syntactic Approach to Combining Functional Notation, Lazy Evaluation, and Higher-Order in LP Systems |editor-last=Hagiya |editor-first=M. |editor2-first=P. |editor2-last=Wadler |book-title=Functional and logic programming, FLOPS 2006 |url=https://books.google.com/books?id=gZzLFFZfc1sC&pg=PA149|access-date=14 January 2011 |year=2006 |publisher=Springer |isbn=978-3-540-33438-5 |page=149 |doi=10.1007/11737414_11 |series=Lecture Notes in Computer Science |volume=3945|url-access=subscription }}</ref> ===Control structures=== {{More citations needed section|date=March 2011}} Lazy evaluation allows control structures to be defined normally, and not as primitives or compile-time techniques. For example, one can define [[if-then-else]] and [[short-circuit evaluation]] operators:<ref>{{cite web |title=utility-ht: Data.Bool.HT.Private |url=https://hackage.haskell.org/package/utility-ht-0.0.16/docs/src/Data.Bool.HT.Private.html#if%27 |website=hackage.haskell.org |access-date=8 January 2022}}</ref><ref>{{cite web |title=The Haskell 98 Report: Standard Prelude |url=https://www.haskell.org/onlinereport/standard-prelude.html |website=www.haskell.org |access-date=8 January 2022 |location=Boolean functions}}</ref> <syntaxhighlight lang="haskell"> ifThenElse True b c = b ifThenElse False b c = c -- or True || b = True False || b = b -- and True && b = b False && b = False </syntaxhighlight> These have the usual semantics, i.e., {{code|ifThenElse a b c|lang=Haskell}} evaluates (a), then if and only if (a) evaluates to true does it evaluate (b), otherwise it evaluates (c). That is, exactly one of (b) or (c) will be evaluated. Similarly, for {{code|EasilyComputed <nowiki>||</nowiki> LotsOfWork|lang=Haskell}}, if the easy part gives '''True''' the lots of work expression could be avoided. Finally, when evaluating {{code|SafeToTry && Expression|lang=haskell}}, if ''SafeToTry'' is '''false''' there will be no attempt at evaluating the ''Expression''. Conversely, in an eager language the above definition for {{code|ifThenElse a b c|lang=Haskell}} would evaluate (a), (b), and (c) regardless of the value of (a). This is not the desired behavior, as (b) or (c) may have [[Side effect (computer science)|side effects]], take a long time to compute, or throw errors. It is usually possible to introduce user-defined lazy control structures in eager languages as functions, though they may depart from the language's syntax for eager evaluation: Often the involved code bodies need to be wrapped in a function value, so that they are executed only when called. === Working with infinite data structures === Delayed evaluation has the advantage of being able to create calculable infinite lists without infinite loops or size matters interfering in computation. The actual values are only computed when needed. For example, one could create a function that creates an infinite list (often called a ''[[Stream (computing)|stream]]'') of [[Fibonacci number]]s. The calculation of the ''n''-th Fibonacci number would be merely the extraction of that element from the infinite list, forcing the evaluation of only the first n members of the list.<ref name="Métayer2002">{{cite conference |last1=Wells |first1=J.B. |last2=Haack |first2=C. |title=Branching Types|editor-first=Daniel |editor-last=Le Métayer |book-title=Programming languages and systems, ESOP 2002 |year=2002 |series=Lecture Notes in Computer Science |volume=2305 |doi=10.1007/3-540-45927-8_9 |publisher=Springer |isbn=978-3-540-43363-7 |pages=129–132|doi-access=free }}</ref><ref name="MachineryLanguages2002">{{cite conference |first=Jan-Willem |last=Maessen |title=Eager Haskell: resource-bounded execution yields efficient iteration |book-title=Proceedings of the 2002 ACM SIGPLAN Haskell Workshop (Haskell '02): Pittsburgh, Pennsylvania, USA; October 3, 2002 |date=2002|publisher=Association for Computing Machinery|isbn=978-1-58113-605-0|pages=38–50 See p. 40 |doi=10.1145/581690.581694}}</ref> Take for example this trivial program in [[Haskell]]: <syntaxhighlight lang="haskell"> numberFromInfiniteList :: Int -> Int numberFromInfiniteList n = infinity !! n - 1 where infinity = [1..] main = print $ numberFromInfiniteList 4 </syntaxhighlight> In the function {{mono|numberFromInfiniteList}}, the value of {{mono|infinity}} is an infinite range, but until an actual value (or more specifically, a specific value at a certain index) is needed, the list is not evaluated, and even then, it is only evaluated as needed (that is, until the desired index.) Provided the programmer is careful, the program completes normally. However, certain calculations may result in the program attempting to evaluate an infinite number of elements; for example, requesting the length of the list or trying to sum the elements of the list with a [[fold (higher-order function)|fold operation]] would result in the program either failing to terminate or running [[out of memory]]. As another example, the list of all Fibonacci numbers can be written in the programming language [[Haskell]] as:<ref name="MachineryLanguages2002"/> <syntaxhighlight lang="haskell"> fibs = 0 : 1 : zipWith (+) fibs (tail fibs) </syntaxhighlight> In Haskell syntax, "<code>:</code>" prepends an element to a list, <code>tail</code> returns a list without its first element, and <code>zipWith</code> uses a specified function (in this case addition) to combine corresponding elements of two lists to produce a third.<ref name="Métayer2002"/> === List-of-successes pattern === {{expand section|date=March 2011}} ===Other uses=== In computer [[windowing system]]s, the painting of information to the screen is driven by ''expose events'' which drive the display code at the last possible moment. By doing this, windowing systems avoid computing unnecessary display content updates.<ref name="Lampson">[http://research.microsoft.com/en-us/um/people/blampson/slides/lazyandspeculative.ppt Lazy and Speculative Execution] [[Butler Lampson]] [[Microsoft Research]] OPODIS, Bordeaux, France 12 December 2006</ref> Another example of laziness in modern computer systems is [[copy-on-write]] page allocation or [[demand paging]], where memory is allocated only when a value stored in that memory is changed.<ref name="Lampson"/> Laziness can be useful for high performance scenarios. An example is the Unix [[mmap]] function, which provides ''demand driven'' loading of pages from disk, so that only those pages actually touched are loaded into memory, and unneeded memory is not allocated. [[MATLAB]] implements ''[[copy on write|copy on edit]]'', where arrays which are copied have their actual memory storage replicated only when their content is changed, possibly leading to an ''out of memory'' error when updating an element afterwards instead of during the copy operation.<ref>{{cite web|url=http://www.mathworks.co.uk/matlabcentral/answers/46551-out-of-memory-when-assigning-values-to-existing-arrays|title=Out of memory when assigning values to existing arrays? |work=MATLAB Answers |publisher=MATLAB Central}}</ref>
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)