5
votes

The Clojure function

(reductions + 0 (cycle [1 1 -1]))

produces a sequence [0 1 2 1 2 3 2 3 4 3 4 5 ...]. Unfortunately, this sequence isn't lazy.

As cycle and reductions are both documented as returning lazy sequences, I expected this combination of those functions to return a lazy sequence as well. Why doesn't it and how can I fix it to return the sequence lazily?

A more complex example that shows the same problem:

(reductions (fn [x f] (f x)) 0 (cycle [inc inc dec]))

(I show this, because this is the kind of version I would like to have working in the end, in case that makes any difference)

1

1 Answers

9
votes

Unfortunately, this sequence isn't lazy.

Oh, yes, it is. We can quickly check that it is lazy by taking its first 10 elements:

(take 10 (reductions + 0 (cycle [1 1 -1])))

This very quickly returns an answer, which proves the sequence is lazy. Were the function not lazy, it would try to realize all the elements in the infinite sequence, and would blow the memory, or hang in an infinite loop.

What happens is that you're typing this func in the REPL, which tries to realize the sequence before showing it to you.

Edit: Use this tip to stop infinite loops if you ever found that you've triggered one or accidentally tried to realize an infinite seq.