(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