Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Why did they create a flatMap method? What is wrong with .map(...).flat()? Can they improve the performance by combining it that much?


Let me preface this with acknowledging that you're entirely correct that you don't really need flatMap. The following is just some background that might explain why it was included.

If you're familiar with C#'s linq and it's reliance on SelectMany it's somewhat easier to see the significance.

In C#'s linq you might write something like:

    from host in sources
    from value in fetch_data_from(host)
    select create_record(value, host)
with flatmap (and some abuse of notation) you can more easily implement this as:

    sources.flatmap( host => fetch_data_from(host)
           .flatmap( value => create_record(value, host))
If you dig even further you'll find that what makes this powerful is that the flatMap, together with the function x => [x], turns arrays into a Monad. The separate functions map and flat also work, but this adds more conditions. Haskell folks tend to prefer flatMap because most of the conditions for a Monad can be encoded in its type signature (except [x].flatMap(x => x) == x, but that one is easy enough to check).


You could optimise either, I don't think that's the point. It's just a convenience that more clearly expresses the intent of the code where it's used. Imagine an example where the callback to map is quite long; seeing the flatMap identifier alerts you to the fact that the callback returns arrays, even before you start reading.

You'll find equivalents in all the JS utility libraries and most functional programming language standard libraries (and languages like Ruby with functional-ish subsets), so there's a lot of evidence that people who write code in that style like to have such a function available.


They could have also implemented flat in terms of flatMap: flatMap(x => x)

I personally feel flatMap is a much more used method than flat, so if you want to remove one, I would remove flat.


> They could have also implemented flat in terms of flatMap: flatMap(x => x)

Flat can flatten any level of nesting (it just defaults to 1), so would be difficult to implement in terms of flatMap.


You could reproduce that behaviour of 'flat' by doing something like:

    function flatten(x, n=1) {
        return n > 0 ? x.flatmap(y => flatten(y, n-1))
                     : x;
    }


You could also blow up your stack as there is no requirement whatsoever that javascript implementations be tail-recursive.


It is very common for people to implement flatmap themselves or get it from a library of higher-order functions. So now people can use flatMap without doing those two things.


And more importantly what is essentially verbatim in your question:

Why is flatMap = map().flat() and not flat().map()


Because the concept originated in languages where function composition is what's emphasized, rather than method chaining.

  flatmap = flat ∘ map




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: