The problem is using rest in map operations. Basically, when your lazy-seq calls the expression: (concat [0 1] (map + fib (rest fib))) to return the ISeq object, a call to rest will be made on the feed (since this is a map parameter, it must be executed first, and then transferred to the card and the card is lazy, but the rest is called before we can achieve laziness). rest will try to call more in the fib, which is the LazySeq object, and the more it will cause the lazy seq to get the next ISeq, which again turns on the whole concat operation, which includes rest , and it continues to go this way while the stack not blown away.
You need to use something that doesn't immediately follow the feed, something like drop :
(def fib (lazy-seq (concat [0 1] (map + fib (drop 1 fib)))))
In addition, in another case, when lazy-seq is inside concat , rest not executed, because it is wrapped inside the lazy-seq operation, which makes the whole expression a function that will be called in the future when the next ISeq is requested.
Hope this clarifies the situation.
source share