106

What is so powerful about flatmap that it deserves such a place in the Scala folklore?

DNA
  • 42,007
  • 12
  • 107
  • 146
Guillaume Belrose
  • 2,478
  • 4
  • 23
  • 24

4 Answers4

105

The story I heard was that two preeminent Scala programmers were pairing when one of them started writing some code like this:

option match {
    case Some ...

At which point the other said "What is this? Amateur hour? Flat map that shit!"

As to what's so powerful about flatMap, well... First, it's the fundamental monadic operator. That means it is a common operation shared by, for example, containers (such as Option, collections, etc), continuations, state, etc. Second, while you can de-construct an Option, that, as opposed to flatMap, is not a monadic operation, so it cannot be as widely applied. Also, it requires too much knowledge about the data you are manipulating.

Note: previously I said matching was slower than flatMap -- the opposite is true as a matter of fact, up to the most recent version of Scala at the time of this writing, 2.10.1.)

Daniel C. Sobral
  • 295,120
  • 86
  • 501
  • 681
  • 4
    I guess I am still at the amateur hour then :-) – Guillaume Belrose Dec 19 '11 at 13:23
  • 74
    Those two programmers were myself and Paul Chiusano. – Apocalisp Dec 19 '11 at 13:34
  • @Apocalisp That's what I thought, but I didn't want to mis-attribute this to anyone. – Daniel C. Sobral Dec 19 '11 at 13:39
  • 1
    If I recall correctly, wasn't #legendofklang manifesting itself on twitter around the same time... which is often the root of the miss-attribution of the flatmap that shit meme? We should make some kind of Scala meme wiki entry; there are some awesome ones now! – timothy Dec 19 '11 at 13:46
  • @timperrett Yes, it was, it that's not a bad idea. We do have a wiki that explains that Apocalisp is Runar, so why not this? – Daniel C. Sobral Dec 19 '11 at 13:54
  • So the advantage of flatMap over just plain map is that the flatten option will decompose Some(Some(Some("string"))) into just plain "string" for any level of Option? – Will Sargent Dec 21 '11 at 07:25
  • 3
    @WillSargent I think that's missing the forest for the trees. The advantage is that it _composes_. If I have a function that depends on four monads, I can write `val res = for (a <- ma; b <- mb; c <- mc; d <- md) yield f(a,b,c,d)`. I can add more monads, remove monads, and it stays the same. Also, note that it doesn't decompose into into `String`, but into `Option[String]`. Though, actually, it doesn't decompose at all. One of the reasons some people don't like using containers as examples for monads is that you can take things out of containers, but not all monads let you do that. – Daniel C. Sobral Dec 21 '11 at 14:20
  • 1
    You can see a link to the discussion quoted here: http://web.archive.org/web/20130627111326/http://beust.com/weblog/2010/07/28/why-scalas-option-and-haskells-maybe-types-wont-save-you-from-null/comment-page-1/#comment-8222 – hawkeye May 23 '14 at 13:14
58

The reasoning behind this phrase is that you can replace a lot of tedious if/then/else code you would write with calls to flatMap (and other higher order functions).

This is especially true for Options (see http://tonymorris.github.io/blog/posts/scalaoption-cheat-sheet/)

But it applies to other monads as well (although I have to admit, I don't exactly understand the details yet myself)

Imagine the situation where you have a collection for which you want to apply a function (or a series of functions) where each function might return null. When you actually use null you code will be riddled with null checks. But if you use Options instead of values, you can just flatmap the values with the desired functions, chaining the functions in the case of multiple functions and get a collection with just the results that aren't null, which in many cases is exactly what you want.

Since that description is rather convoluted the shorter advice "just flatmap that shit" established itself.

Abe Voelker
  • 30,124
  • 14
  • 81
  • 98
Jens Schauder
  • 77,657
  • 34
  • 181
  • 348
12

The crucial thing about flatMap is that it's Scala's representation of the monadic bind operation. There are numerous tutorials on the web explaining the purpose of monads and why exactly they're so useful; James Iry has one which goes into some detail.

k0pernikus
  • 60,309
  • 67
  • 216
  • 347
Submonoid
  • 2,809
  • 2
  • 20
  • 25
  • 4
    I think this is the correct answer, `Option` is just one of many `flatMap` use cases. Of course, if you want to observe monads in their "natural habitat", you should check out Haskell. The only difference is that Haskellers say: "Just >>= that shit!" – Landei Dec 19 '11 at 14:44
  • Thanks for the link to the article, I found it very useful. I also went back to the "For expressions revisited" chapter in Programming in Scala which sheds some light on for loops and their use of filter, map, flatMap and flatten. – Guillaume Belrose Dec 20 '11 at 10:57
10

Runar Bjarnason is the person you're looking for for the origin.

Realising why it's so powerful is something that can only come with time to be honest. The Option class is the best place to start for seeing how you would repeatedly flatMap a series of lookups (for example) into a final result.

Sean Parsons
  • 2,832
  • 21
  • 17