Reputation: 481
I can't understand why this lazy-seq causes a stackoverflow, and why not when you pass the sequence to dorun:
(defn very-lazy [s]
(lazy-seq
(if (seq s)
[(first s) (very-lazy (rest s))]
[])))
(dorun (very-lazy (range 200000000)))
>nil
(take 2 (very-lazy (range 20000000))
>...(1577 (java.lang.StackOverflowError
If it's lazy then take 2
should cause the lazy seq to iterate only two times, why doesn't happen and why dorun works?
Upvotes: 4
Views: 1793
Reputation: 3752
In your example function returns lazyseq (0 (1 (2 (3 (...)))))
. That's why dorun
runs without stackoverflow (there is sequence of two elements 0
and (1 (2 (...)))
that dorun
doesn't evaluate) and second
fails (it returns infinite nested sequences that repl tries evaluate to print out).
I guess you're looking for this solution
(defn very-lazy [s]
(lazy-seq
(if (seq s)
(cons (first s) (very-lazy (rest s)))
[])))
(take 10 (very-lazy (range 200000000)))
-> (0 1 2 3 4 5 6 7 8 9)
Upvotes: 3