Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The reason that the clojure standard library only has fold-left (reduce) is actually very subtle and it is because clojure isn't lazy enough to get the main benefit of fold-right.</p> <p>The main benefit of fold-right in languages like haskell is that it can actually short-circuit. If we do <code>foldr (&amp;&amp;) True [False, True, True, True, True]</code> the way that it actually gets evaluated is very enlightening. The only thing it needs to evaluate is the function <code>and</code> with 1 argument (the first <code>False</code>). Once it gets there it knows the answer and does not need to evaluate ANY of the <code>True</code>s.</p> <p>If you look very closely at the picture: </p> <p><img src="https://i.stack.imgur.com/3TUAU.png" alt="enter image description here"> </p> <p>you will see that although conceptually fold-right starts and the end of the list and moves towards the front, in actuality, it starts evaluating at the FRONT of the list.</p> <p>This is an example of where lazy/curried functions and tail recursion can give benefits that clojure can't.</p> <h2>Bonus Section (for those interested)</h2> <p>Based on a recommendation from vemv, I would like to mention that Clojure added a new function to the core namespace to get around this limitation that Clojure can't have the lazy right fold. There is a function called <code>reduced</code> in the core namespace which allows you to make Clojure's <code>reduce</code> lazier. It can be used to short-circuit <code>reduce</code> by telling it not to look at the rest of the list. For instance, if you wanted to multiply lists of numbers but had reason to suspect that the list would occasionally contain zero and wanted to handle that as a special case by not looking at the remainder of the list once you encountered a zero, you could write the following <code>multiply-all</code> function (note the use of <code>reduced</code> to indicate that the final answer is <code>0</code> regardless of what the rest of the list is).</p> <pre><code>(defn multiply-all [coll] (reduce (fn [accumulator next-value] (if (zero? next-value) (reduced 0) (* accumulator next-value))) 1 coll)) </code></pre> <p>And then to prove that it short-circuits you could multiply an infinite list of numbers which happens to contain a zero and see that it does indeed terminate with the answer of <code>0</code></p> <pre><code>(multiply-all (cycle [1 2 3 4 0])) </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload