4
votes

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?

1

1 Answers

3
votes

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)