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