<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Clojure Q&amp;A - Recent questions tagged lazy-seq</title>
<link>https://ask.clojure.org/index.php/tag/lazy-seq</link>
<description></description>
<item>
<title>Stack overflow with lazy-seq</title>
<link>https://ask.clojure.org/index.php/13937/stack-overflow-with-lazy-seq</link>
<description>&lt;p&gt;I'm learning Clojure by doing problems from &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/PEZ/rich4clojure&quot;&gt;rich4clojure&lt;/a&gt; repo. &lt;a rel=&quot;nofollow&quot; href=&quot;https://gist.github.com/PEZ/9dcf23444c51883c4318d69efcd5e9f7&quot;&gt;Problem 147&lt;/a&gt; asks one to create a function which returns a lazy sequence of rows following rules of Pascal triangle given initial row. For example, for [3 1 2], the next row is [3 4 3 2]. Here's my solution:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(defn pascal
      ([row] (lazy-seq (cons row (__ row :next))))
      ([row _]
       (lazy-seq
        (let [next-row (map #(apply +' %) (partition 2 1 (concat '(0) row '(0))))]
          (cons next-row (pascal next-row :next)))))))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I decided to test it and compare it with solutions others came up with. For example, one user wrote:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(defn pascal [coll]
(lazy-seq
  (cons coll
        (pascal (let [middle (map #(apply +' %) (partition 2 1 coll))]
                       (concat [(first coll)] middle [(last coll)]))))))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I time both solutions by evaluating:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;time (nth (nth (pascal [1]) 400) 50))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and it turns out that mine is faster (which is sort of expected because the other user relies on &lt;em&gt;last&lt;/em&gt; which is O(n)). However, when I try to calculate 1000th row, I get stack overflow error only in case of my function. I'm struggling to see why this happens because I shouldn't be increasing the stack size. What am I missing?&lt;/p&gt;
</description>
<category>Clojure</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/13937/stack-overflow-with-lazy-seq</guid>
<pubDate>Sun, 02 Jun 2024 19:14:33 +0000</pubDate>
</item>
<item>
<title>Infinite lazy sequence expands until JVM runs out of memory</title>
<link>https://ask.clojure.org/index.php/13111/infinite-lazy-sequence-expands-until-jvm-runs-out-of-memory</link>
<description>&lt;p&gt;Hello, I am new to Clojure and to lazy sequences.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(defn get-biggest-prime-factor [num]
  (let [max-check (inc (Math/sqrt num))
        lazy-primes (filter-lazy-seq is_prime naturals)]
    (loop [prime (first lazy-primes)
           max-factor 1]
      (cond (&amp;gt;= prime max-check) max-factor
            (= 0 (rem num prime)) (recur (first (rest lazy-primes)) (first lazy-primes))
            :else (recur (first (rest lazy-primes)) max-factor)))) )
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;naturals&lt;/strong&gt; is an infinite lazy sequence of 1,2,3 ... ,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;filter-lazy-seq&lt;/strong&gt; is a function, which returns a lazy sequence derived from second argument. Every element of sequence is verified by first argument, which is a predicate&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;is-prime&lt;/strong&gt; is a function that check if a number is prime&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Any help is appreciated.&lt;/p&gt;
</description>
<category>Sequences</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/13111/infinite-lazy-sequence-expands-until-jvm-runs-out-of-memory</guid>
<pubDate>Sat, 29 Jul 2023 23:20:23 +0000</pubDate>
</item>
<item>
<title>lazy-seq in ClojureScript does not allow for self-referential sequences</title>
<link>https://ask.clojure.org/index.php/11787/lazy-clojurescript-does-allow-self-referential-sequences</link>
<description>&lt;p&gt;For context, started on Slack at &lt;a rel=&quot;nofollow&quot; href=&quot;https://clojurians.slack.com/archives/C03S1L9DN/p1650480331191719&quot;&gt;https://clojurians.slack.com/archives/C03S1L9DN/p1650480331191719&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This code works just fine on CLJ but fails with &lt;code&gt;StackOverflowError&lt;/code&gt; on CLJS:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(def primes (remove
             (fn [x]
               (some #(zero? (mod x %)) primes))
             (iterate inc 2)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The vital difference between CLJ and CLJS in this case is that in the former, &lt;code&gt;lazy-seq&lt;/code&gt; ends up wrapping its whole body in a function with &lt;code&gt;^:once&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The reasoning why it works that way is because in the code above, the inner &lt;code&gt;primes&lt;/code&gt; is a closed over value, it becomes a local. When the body fn of a &lt;code&gt;lazy-seq&lt;/code&gt; (the one with &lt;code&gt;^:once&lt;/code&gt;) is called the second time, its locals are &lt;code&gt;nil&lt;/code&gt;, so that inner &lt;code&gt;primes&lt;/code&gt; is also &lt;code&gt;nil&lt;/code&gt;. And iteration stops.&lt;br&gt;
In CLJS, there's no &lt;code&gt;:once&lt;/code&gt; and no locals clearing, so the inner &lt;code&gt;primes&lt;/code&gt; is never &lt;code&gt;nil&lt;/code&gt;, and the execution keeps on going into that &lt;code&gt;fn&lt;/code&gt; without even calling that &lt;code&gt;zero?&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Even if the reasoning doesn't sound plausible, the hypothesis that it's indeed &lt;code&gt;:once&lt;/code&gt; that's to blame for the difference can be easily confirmed by implementing &lt;code&gt;lazy-seq&lt;/code&gt; in CLJ without &lt;code&gt;:once&lt;/code&gt; and noticing that it leads to &lt;code&gt;StackOverflowError&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;It's unclear to me what to do in this case, but perhaps at least a note on the &lt;a rel=&quot;nofollow&quot; href=&quot;https://clojurescript.org/about/differences&quot;&gt;https://clojurescript.org/about/differences&lt;/a&gt; page should be made about it.&lt;/p&gt;
</description>
<category>ClojureScript</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/11787/lazy-clojurescript-does-allow-self-referential-sequences</guid>
<pubDate>Wed, 20 Apr 2022 21:02:56 +0000</pubDate>
</item>
</channel>
</rss>