The inimitable Chouser has written an exhaustive analysis of the many ways to flatten a sequence of sequences in Clojure.
We are in complete agreement on the subject of flatten: Don’t use it. It’s much more complicated than it looks, and could come back to bite you later.
As for myself, I would usually write mapcat identity
, because I think of flatten
as a sign of a missing mapcat
. There are a number of other options, some of which hadn’t occurred to me, such as Chouser’s preferred mapcat seq
. I like the way mapcat seq
indicates that we are working with a sequence of sequences, although it’s not quite as lazy as the alternatives.
I wouldn’t have chosen apply concat
, partly because I’ve been suspicious of concat ever since I first encountered a lazy stack overflow. But apply concat
does not suffer from that risk, at least not as far as I can tell. It just seems … inapt. That apply
sticks out at me.
But as Chouser shows, apply concat
is arguably the most-primitive — dare we say “simplest”? — version, as it is used in the implementation of mapcat.
So where does this leave me? I haven’t changed my opinion of flatten
. I still think that any time you have a sequence-of-sequences there’s a good chance that, somewhere, you will find a map
that should have been a mapcat
. But on those occasions where a flatten-like operation really can’t be avoided, maybe I will learn to appreciate the subtlety of apply concat
.