When using reducers, I will occasionally use foldcat to "realize" the transformed collection through the reducer chain. For downstream code, its preferable to have a fully realized standard clojure collection like vec
. This is often the case when updating core collection code to use reducers for performance reasons:
Note the following works just fine:
(->> (repeat 2 3) (vec) (r/map inc) (r/foldcat) (vec))
=> [4 4]
If the input gets large enough however, this triggers the parallel behavior which changes the return type from Array to Cat and causes the last vec
to choke:
(->> (repeat 513 3) (vec) (r/map inc) (r/foldcat) (vec))
Execution error at user/eval19976 (form-init6687476487684153971.clj:1).
Unable to convert: class clojure.core.reducers.Cat to Object[]
I surmise that the "correct" way to do this is to use (into [])
instead of vec
in the last position which works just fine.
That said, this came as fairly surprising behavior given that seq
and into
work just fine on both Array
and Cat
. Its also quite dangerous because such code can function quietly in production until the input data grows passed a certain threshold. Is there pragmatic reason that seq
works for Cat
but vec
doesn't?