{"id":830,"date":"2009-06-24T11:27:35","date_gmt":"2009-06-24T09:27:35","guid":{"rendered":"http:\/\/www.navision-blog.de\/2009\/06\/24\/f-bootcamp-questions-and-answers-part-iii-lazy-evaluation\/"},"modified":"2009-06-24T12:22:14","modified_gmt":"2009-06-24T10:22:14","slug":"f-bootcamp-questions-and-answers-part-iii-lazy-evaluation","status":"publish","type":"post","link":"http:\/\/www.navision-blog.de\/blog\/2009\/06\/24\/f-bootcamp-questions-and-answers-part-iii-lazy-evaluation\/","title":{"rendered":"F# BootCamp &ndash; Questions and Answers &ndash; part III &ndash; Lazy evaluation"},"content":{"rendered":"<p>This is the third part in a \u201cQuestions and Answers\u201d-series about the <a href=\"http:\/\/dotnet-leipzig.de\/veranstaltungen\/net-bootcamp-2009-5\/\">F# BootCamp in Leipzig<\/a>. This time we will look at lazy evaluation.<\/p>\n<h5>Question 5 \u2013 What is the difference between \u201cLazy Evaluation\u201d and \u201cEager evaluation\u201d?<\/h5>\n<blockquote>\n<p><b>Lazy evaluation<\/b> is a technique of delaying a computation until the result is required. If we use <strong>eager evaluation<\/strong> an expression is evaluated as soon as it gets bound to a variable.<\/p>\n<\/blockquote>\n<p>One participant answered that lazy evaluation is used in most programming languages to calculate boolean expressions faster. For instance in the expression \u201cx() <strong>or<\/strong> y()\u201d the function y() is never called if x() returns true. <\/p>\n<p>Of course this answer is correct, but this &quot;<a href=\"http:\/\/en.wikipedia.org\/wiki\/Short-circuit_evaluation\">short-circuit evaluation<\/a>&quot; is only a special case of lazy evaluation. The program would also work correctly without it. But if we want to define an infinite sequence then we can not use eager evaluation. Let\u2019s look at an example:<\/p>\n<pre class=\"code\"><span style=\"color: green\">\/\/ val fibs: seq&lt;int&gt;\n<\/span><span style=\"color: blue\">let <\/span>fibs = (1, 1) |&gt; Seq.unfold(<span style=\"color: blue\">fun <\/span>(n0, n1) <span style=\"color: blue\">-&gt; <\/span>Some(n0, (n1, n0 + n1)))<\/pre>\n<p>We do not need to understand the concrete syntax of this code here. We\u2019ll discuss this later. Let\u2019s just say fibs is bound to an infinite sequence (IEnumerable&lt;int&gt;) of Fibonacci numbers. You could also write this in C#:<\/p>\n<pre class=\"code\"><span style=\"color: gray\">\/\/\/ &lt;summary&gt;\n\/\/\/ <\/span><span style=\"color: green\">Infinite sequence of Fibonacci numbers.\n<\/span><span style=\"color: gray\">\/\/\/ &lt;\/summary&gt;\n<\/span><span style=\"color: blue\">public static <\/span><span style=\"color: #2b91af\">IEnumerable<\/span>&lt;<span style=\"color: blue\">int<\/span>&gt; Fibs()\n{\n    <span style=\"color: blue\">var <\/span>n0 = 1;\n    <span style=\"color: blue\">var <\/span>n1 = 1;\n    <span style=\"color: blue\">while<\/span>(<span style=\"color: blue\">true<\/span>)\n    {\n        <span style=\"color: blue\">yield return <\/span>n0;\n        <span style=\"color: blue\">var <\/span>t = n1;\n        n1 = n1 + n0;\n        n0 = t;\n    }\n}<\/pre>\n<p>The trick is IEnumerable evaluates the elements lazy. Only at the time we take an element from the sequence the element will be computed:<\/p>\n<pre class=\"code\">fibs\n  |&gt; Seq.take 10\n  |&gt; Seq.to_list\n  |&gt; printfn <span style=\"color: maroon\">&quot;%A&quot; <\/span><span style=\"color: green\">\/\/ prints [1; 1; 2; 3; 5; 8; 13; 21; 34; 55]<\/span><\/pre>\n<p>If we would use eager evaluation then \u201cSeq.take\u201d would never been called. But we can go one step further. If we want to get the first 10 even-valued terms in the Fibonacci sequence, we can write this code:<\/p>\n<pre class=\"code\">fibs \n  |&gt; Seq.filter (<span style=\"color: blue\">fun <\/span>fib <span style=\"color: blue\">-&gt; <\/span>fib % 2 = 0) <span style=\"color: green\">\/\/ lazy (via pipe)\n  <\/span>|&gt; Seq.take 10                         <span style=\"color: green\">\/\/ lazy (via pipe)\n  <\/span>|&gt; Seq.to_list                         <span style=\"color: green\">\/\/ eager\n  <\/span>|&gt; printfn <span style=\"color: maroon\">&quot;%A&quot; \n  \n<\/span><span style=\"color: green\">\/\/ prints [2; 8; 34; 144; 610; 2584; 10946; 46368; 196418; 832040]<\/span><\/pre>\n<p>This would be a little bit tricky if we use eager evaluation, but of course this nice laziness comes with some costs for storing intermediate results (and code). So eager evaluation is still often the better choice and sometimes (e.g. <em>DateTime.Now()<\/em>) it makes no sense to use lazy evaluation \u2013 at least not if we don\u2019t reevaluate the function.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is the third part in a \u201cQuestions and Answers\u201d-series about the F# BootCamp in Leipzig. This time we will look at lazy evaluation. Question 5 \u2013 What is the difference between \u201cLazy Evaluation\u201d and \u201cEager evaluation\u201d? Lazy evaluation is a technique of delaying a computation until the result is required. If we use eager [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[23,448,8],"tags":[540,664,555],"_links":{"self":[{"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/posts\/830"}],"collection":[{"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/comments?post=830"}],"version-history":[{"count":3,"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/posts\/830\/revisions"}],"predecessor-version":[{"id":833,"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/posts\/830\/revisions\/833"}],"wp:attachment":[{"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/media?parent=830"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/categories?post=830"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/tags?post=830"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}