What are the differences between mapcat in Clojure and flatMap in Scala in terms of what they operate on?

clojure, scala

Solution

The real difference is that flatMap is polymorphic on the type, and mapcat isn't. So any type can decide to provide a "flatMap" like behaviour. That's how you get things like Futures being flatMapable.

In Clojure, mapcat is specific to the seqable type. Any seqable can be coerced into a sequence, and all sequence can be mapped and concatenated. The mapcat implementation will check if the input is seqable, if so, it will call seq on it to coerce it to a sequence, and then it will map and cat that sequence and give you back a sequence. You don't get back a result of the original type.

In Scala, if you implement IterableLike trait (I think that's the right interface), you get the default flatMap implementation which is a bit like the Clojure one minus the coercion to sequence. But, many types also provide a custom implementation of flatMap, making it generic in that way.

Problem

I understand the equivalent to `flatMap` in Scala is `mapcat` in Clojure. I have an inkling that `mapcat` in clojure only works with sequences, unlike `flatMap` in Scala which is more flexible. My question is - what are the differences between `mapcat` in Clojure and `flatMap` in Scala in terms of what they operate on? Assumptions: - I understand that Scala has a rich type system and Clojure has optional typing - I'm interested to know if the is a limitation in the parameters that mapcat accepts that make it only have a subset of `flatMap`s functionality.

Original source