Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>This is not an answer to your question, but in the interest of writing "nice" clojure code, I wanted to point out a few things with your example.</p> <p>One of the benefits of the functional style is the ability to compose functions together. But if you take a look at the functions you've written, they individually don't do much without depending on functionality provided elsewhere. </p> <p>For example, <code>stream-builder</code> just returns a two-element list of <code>n</code> and an anonymous function to handle pseudo-recursion.</p> <p>My guess is that you were trying to go for a lazy sequence, but doing it that way requires support functions that are aware of the implementation details to realize the next element, namely, <code>stream</code> and <code>second$</code>. Thankfully you can instead accomplish it as follows:</p> <pre> (defn stream-builder [f x] ; f is idiomatic for a function arg (lazy-seq ; n is idiomatic for a count, so use x instead (cons x (stream-builder f (f x))))) </pre> <p>The above will actually return an infinite sequence of values, so we need to pull out the limiting behavior that's bundled inside <code>stream</code>:</p> <pre> (defn limit [n coll] ; coll is idiomatic for a collection arg (lazy-seq ; flipped order, fns that work on seqs usually take the seq last (when (pos? n) (when-let [s (seq coll)] (cons (first s) (limit (dec n) (next s))))))) </pre> <p>The above will <i>lazily</i> return up to <code>n</code> elements of <code>coll</code>:</p> <pre> user=> (limit 5 (stream-builder inc 1)) (1 2 3 4 5) </pre> <p>In the end, each function does one thing well, and is composable with other functions:</p> <p>Finally, you defined <code>odd</code> to be the lazy sequence of odd integers. The danger is that sequence is going to stick around as it gets realized (this is known as "holding onto the head" of a sequence). This can unnecessarily take up excess memory to hold onto every element ever realized, and prevents garbage collection.</p> <p>To solve this, either do not def the lazy sequence, or def it with the limit, e.g.:</p> <pre> (def odds (limit 23 (stream-builder #(+ 2 %) 1))) </pre> <p>For future reference, what we have just written is available in the core lib as <code>iterate</code> and <code>take</code>, respectively:</p> <pre> user=> (take 5 (iterate inc 1)) (1 2 3 4 5) </pre>
 

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