Running this works as expected:
(defn long-seq [n]
(lazy-seq (cons
(list n {:somekey (* n 2)})
(long-seq (+ n 1)))))
(take 3 (long-seq 3))
; => ((3 {:somekey 6}) (4 {:somekey 8}) (5 {:somekey 10}))
However I would like to do the same thing with a vector:
(defn long-seq-vec [n]
(lazy-seq (into
(vector (list n {:somekey (* n 2)}))
(long-seq-vec (+ n 1)))))
(take 3 (long-seq-vec 3))
This gives me a stack overflow. Why?
The main reason is that vectors aren't lazy - so the
into
call greedily consumes the recursive sequences produced bylong-seq-vec
and results in a stack overflow. As a corollary of this, it's not possible to create an infinite vector (in general, you can only create an infinite data structure if it is lazy or cyclic).It works in the first example because
cons
is quite happy to behave lazily when consing onto the front of a lazy sequence, so the sequence can be infinite.Assuming you actually want an infinite sequence of vectors I'd suggest something like:
Or as an alternative, you can use
for
which is lazy in itself:I prefer this as it avoids the
lazy-seq
/cons
boilerplate, avoids recursion and is slightly more clear in expressing what your function does... it's a little more "declarative" if you like. You could also usemap
in a similar way.