(reduce concat (repeat 10000 []))
I understand that flatten
is probably a better way to do this but I am still curious as to why this causes an error.
It's because concat
produces a lazy sequence.
So, when you're calling
(concat a b)
no actual concatenation is done unless you're trying to use the result.
So, your code creates 10000 nested lazy sequences, causing StackOverflow error.
I can see two ways to prevent it from throwing an error.
First way is to force concat
execution using doall
function:
(reduce (comp doall concat) (repeat 10000 []))
Second way is to use greedy into
function instead of lazy concat
:
(reduce into (repeat 10000 []))
As for your suggestion about using flatten
, it's not a good solution, because flatten
is recursive, so it'll try to flatten all nested collections as well. Consider the following example:
(flatten (repeat 3 [[1]]))
It will produce flattened sequence (1 1 1)
instead of concatenated one ([1] [1] [1])
.
I think that the best solution would be to use concat
with apply
:
(apply concat (repeat 10000 []))
Because it will produce single lazy sequence without throwing StackOverflow error.
concat
is lazy, so all the calls to concat are saved up until the results are used. doall
forces lazy sequences and can prevent this error:
user> (reduce concat (repeat 10000 []))
StackOverflowError clojure.lang.RT.seq (RT.java:484)
user> (reduce (comp doall concat) (repeat 10000 []))
()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With