4

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 Answer 1

3

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)
Sign up to request clarification or add additional context in comments.

2 Comments

Evaluating lazy seqs in the REPL often causes problems trying to print the results that would not occur in normal usage, e.g. just typing (repeat 1) in the REPL is a bad idea.
You can set *print-length* to limit output, e.g. for (set! *print-length* 10) (repeat 1) will be outputted as (1 1 1 1 1 1 1 1 1 1 ...) in repl.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.