back
125 comments
PLT_HULK would have something to say about it :) https://twitter.com/plt_hulk/status/397822619736870912
I feel like this rush to adopt functional language features in non-functional languages is like deciding to shoehorn a jet engine onto your hot-air balloon. Yes, it can be done but ... see PLT_HULK.
These two functions are equivalent:

  const f1 = function(s) {
    let data;
    try {
      data = JSON.parse(s);
    } catch (err) {}

    if (data != null &&
        data.a != null &&
        data.a.b != null &&
        typeof data.a.b.c === 'string') {
      let x = parseFloat(data.a.b.c);
      if (x === x) {
        return x;
      }
    }
    return null;
  };

  const f2 =
  R.pipe(S.parseJson,
         R.chain(S.gets(['a', 'b', 'c'])),
         R.filter(R.is(String)),
         R.chain(S.parseFloat),
         S.fromMaybe(null));
Note that in the first function we have an unsafe expression,

  data.a.b.c
which we must guard with null/undefined checks. Unsafe expressions can easily get out of sync with their corresponding guards.

We can apply functional programming concepts to JavaScript code to obviate the need for null/undefined checks. The fact that we can't have all the benefits of FP in JS shouldn't dissuade us from taking advantage of the ideas which are applicable.

> I feel like this rush to adopt functional language features in non-functional languages is

Very few languages in use are fairly described as "non-functional"; pretty much any structured programming languages that supports function pointers supports the functional paradigm. A language doesn't have to be pure to support functional programming.

I detest how everyone always takes monads, a quite simple concept, and completely butchers the explanation. I think it's likely in large part a reason for a lack of their acceptance and use.
I'd say you're now almost guilt-edged required to provide us with your simple explanation here. But i'll warn you, i've been nicely flummoxed by competing 'simple' explanations in this forum previously: "A Monad is an object whose methods return monads.", "They're simply a highly specific way of chaining operations together.", "You know how jQuery methods can string out multiple methods with periods? That's what monads are.", "Monads are merely an analogy to control flow what abstract data types are to data."
Haskell is a pure language. Purity is a concept that is absolutely bizarre to the real world, where adding two numbers together results in tons of side effects (load into registers, oops, have to load cache lines, alter memory, raise the ambient temperature, etc. etc.). However, the idea of pure functions is useful. So we make our basic program blocks from pure functions that don't "do" stuff, but just transform values.

However, we must chain these into useful programs somehow. Monad is the type name chosen in Haskell for the construct that does this. It's kind of simple if you work it backwards from the syntax. You want to be able to say

    do
      a <- readInt
      b <- readInt
      add a b
      print
The first two can fail, rely on side effects and the last one is purely a side effect. The only pure function is add, which can't work if a or b aren't there. Monads serve as a way to represent the real-world-ness without it seeping into the add function. You can think of each line as a closure getting the next value from the previous line. So readInt returns a Maybe Int. If it returns a Nothing, the next closure is simply skipped. You can insert a check after the add, if you want to, to see if you got Nothing and alert the user, etc. However, the basic idea is that the program does not crash with a NullPointerException. We know what to do if we get Nothing. The add function doesn't need to concern itself with that.

Hence, the Monad. It wraps a real world concern around a type (it has a type constructor). You must be able to make one from a concrete value that is unburdened with exceptional state (it has the unit function). You must be able to call pure functions on these monadic values without the side state seeping into the function (it has the bind function).

Edit: the reason you don't see Monads in other languages is because they're not essential to them. You can do stuff in C without Monads. To Haskell, Monads are like the Higgs boson. It's how you bind stuff together.

So this is going to sound snarky and/or stupid at first, but: Monads are functors with a 'join' ("flatten") operation.

A functor is a type parameterized by another type[1], say 'a', with a function 'fmap' taking a function 'a -> b', yielding the original object except that its type is now parameterized by 'b'[2]. A monad's 'join' operation takes 'f (f a)' onto 'f a'.

On top of this, there are certain laws which must be obeyed. The functor laws amount to saying that 'fmap' can't change anything about the object (including structure) which doesn't depend on the parameter 'a', but must change everything which does depend on 'a'. The monad laws amount to saying that 'join' has a certain associative structure[3], and also that there is a left- and right-identity 'return: a -> f a'.

[1] a la Java generics, for those not into FP

[2] i.e., fmap has type 'forall a b. (a -> b) -> (f a -> f b)'

[3] Explaining exactly what this associative structure is in these terms is tricky, since 'join' as described is unary. Here's where you have to introduce the function 'bind', '(\f -> join . fmap f)': 'bind g . bind f' === 'bind (bind g . f)'. But it's really not essential; the most intuitive consequence is that Haskell's 'do' notation works like you want it to.

https://www.youtube.com/watch?v=yvwaxYro4FU

I've struggled with blog posts about monads countless times. Maybe I just find it easier to listen to some explanations rather than read them.

A monad has two operations - bind and return - and they're used for chaining
s/guilt/gilt/
Let's try this one.

"A monad" isn't a thing, but we can ask what it takes for something to "have monad-nature" or "be a monad". For this to occur our something must be three things, a triple

    (T, mu, eta)
The names are all meaningless so for the moment they just get short letters.

T must be what's known as a Functor. For PLs really, though, it's even more specific. It's an "endofunctor on the type category of your language". What this means is simple

* For any (static) type `a` in your language, `T a` is also a static type.

* For any function `f` from type `a` to type `b`, `T f` is a function from type `T a` to `T b`.

If your language doesn't have static types then you can approximate this by pretending that it does. Also note that `T f` is not usually the syntax used, but it'll do for now.

Now to make a monad we take any choice of Functor `T` and give it two operations. `eta` takes values in type `a` to values in type `T a` while `mu` takes values in type `T (T a)` to values in type `T a`. In other words they give you a "layer manipulation toolkit".

They must follow laws as well, but these laws are all "common sense laws" which allow you to think of values in the following types: `a`, `T a`, `T (T a)`, `T (T (T a))`, `T (T (T (T a)))`, ... as all being the same as values with just one layer: `T a`. This is the "flatten" idea.

And there you have it! Anything at all which can be regarded as equivalent to one of these triples following this design and laws is a monad!

---

So the real question is why should someone care? The answer is simple.

Lots of things have monad-nature in a typed language. By recognizing their common nature we can (a) see them in a new light full of perhaps previously unknown similarities, (b) share terminology lightening the burden of how to use them, (c) write generic operations which work over any monad and expect them to work with each specific one in a similar way, (d) introduce new syntactic sugar which is built entirely from (mu, eta) and expect it to work similarly for every thing with monadic-nature, (e) begin to form theories and impressions of "what it means to be a monad".

The reasons (a-d) show up all the time once you recognize this pattern since monads are really common.

Reason (e) is what everyone wants to hear about but it's hard to talk about without being super arm-wavey. But I'll try.

In order to provide the operation `mu :: T (T a) -> T a` the type `T a` must be able to "internalize itself" without losing too much information. In order to follow the laws, one bit of important information is an idea of sequence or nesting—but one unique to each particular monadic triple.

In this way monads are a very, very, very general way of talking about sequencing or nesting.

What makes thins interesting is that you can see imperative languages as being about sequencing or nesting as well. If you have a listing of statements { X ; Y ; Z } then you can see { Y ; Z } as being nested in the execution context that X created and { Z } being nested in the execution context that { X ; Y } created.

This would maybe make you think that imperative languages have monad nature and indeed they do. This leads to an interesting study of questions like "For some given imperative language, what is a pure-functional representation of the monad representing it?" which sometimes has interesting answers.

What's even more interesting is that one example of reason (d) above is to introduce a syntax sugar which makes any monad look a bit like an imperative language. This leads to an interesting study of questions like "What does the imperative language for some monad X feel like?"

So if you really like imperative languages and recognize that there's a larger design space here that most have any familiarity with then monads are a good thing to keep an eye out for.

Yeah, if we're talking about JavaScript, the explanation should start with promises. It's a pattern lots of people know, and it's a very real-world example. No need to front-load the explanation with a bunch of complication before people even know why they should care.

I suspect some people (not saying this author) butcher the explanation intentionally. Makes it seem like an ineffable topic that only the smartest programmer can understand.

I agree, and I actually think a better word for `bind` is `then`.

For anyone unfamiliar, the `then` of Promises corresponds to the monadic `bind` or `flatMap` (if the given function returns a Promise) or the functorial `map` (if the given function returns a plain value).

A monad then is just the interface shared between Promises (`then` and `resolve`, collections (`flatMap` and `wrap`), etc.

The hard part for me was visualising the pattern for more complicated types like parsers (functions from strings to results) and continuations.

Every time I see one of the monad articles I think "this looks like promises, except it has a nicer syntax in Haskell".

Is there any reason to use monads in (let's say) Javascript rather than promises? Are there any performance gains?

Crockford’s Paradox:

Once you understand and fully appreciate Monads, you lose the ability to explain them to other people.

This might actually be generalizable to any design pattern of sufficient utility.
If it were truly a simple concept, it might not need so many tutorials and explanations.
I think Monads have been placed on a pedestal such that many consider that you are not a true programmer until you can understand them.

Consequently, whenever someone feels they understand Monads they are compelled to write a tutorial to demonstrate their understanding and consequent elevation to "true programmer" status. There is a large audience for these tutorials as all the "non-true" programmers struggle to reach this stage.

I certainly only wanted to understand Monads because they sounded cool, not really because I wanted to become a better programmer. Although I certainly found this to be quite a positive side-effect in my struggles to become a "true" programmer.

It's simple but very abstract. The hard part isn't the concept, it's connecting it to anything you're actually familiar with.
Perhaps they are much simpler than everyone believes they are and the tutorials are the result of people overcomplicating them.
The issue here is that too many beginning functional programmers insist on trying to "understand" monads before using them (and get stuck).

They don't teach you number theory before arithmetic in primary school. Similarly, you don't need to understand monads before you use IO.

Or perhaps just the opposite. The more genuinely simple a concept is the more likely you are to run into it. Since nearly every programming language on the planet can be rightfully said to be built implicitly atop a single monad... it's a very pervasive concept!
The simplicity is an illusion. While monads are not complex, the concept is very abstract relative to the imperative languages most people program in.

Think about it. In python there's really no syntactic sugar to place something in a container, so the concept doesn't really exist in python until you invent it using other python language primitives. So when you tell a python guy about a burrito, he really has no language analogue to think about. When I tried to learning about the maybe monad, I looked up a tutorial that taught it in python... Big mistake. I was thinking why the hell would people go out of there way to wrap that shit up in a burrito when they can just do a goddamn try exception... It made no sense to me, and even now, it still doesn't make sense for python. Only when I learned about haskell did I realize how the maybe monad makes sense for haskell.

I think most people learn about monads through haskell or any other language with a similar type system. It'd be interesting to hear peoples' experiences about how they grokked the concept.

I think Maybe monad could be really useful in Swift (Apple's new language). Some people use it for chaining up the optional type. However, I found that the lack of functional feature such as curried parameters in swift makes it less useful.
OK, go on, explain what else it is, rather than accidental convention of how to ensure an order of evaluation of a pair of expressions in a particular lazy pure-functional language?

Erlang, for example, being functional but strict language, requires no monads. So does Standard ML. In these languages a monads would be a useless, redundant abstraction which will only clutter the code.

I've been using Monads in Scala for not throwing wild exceptions, but still being able to stop the computation immediately if needed. For example you want to validate things with a Validation[A] type, which can either be Valid or Invalid. The binding function in Scala is called flatMap, so flatMap for a Valid value returns a lambda having the included value as the parameter and Invalid doesn't have a function call, so the flatMap operation stops.

Example:

  Valid("userId").flatMap(userId =>
    Invalid("address").map(address => User(id = userId, address = address))
would stop for the address validation, because the flatMap for a Validation is specified as:

  def flatMap[B](f: A => Validation[B]): Validation[B] = this match {
    case Valid(value) => f(value)
    case Invalid(value) => Invalid(value)
  }
and map for a Validation is specified as:

  def map[B](f: A => B): Validation[B] = this match {
    case Valid(value) => Valid(f(value))
    case Invalid(value) => Invalid(value)
  end
And of course we can have a bit of syntactic sugar to not nest dozens of flatmaps, in Scala we use for:

  for {
    userId <- Valid("userId")
    address <- Invalid("address")
  } yield {
    User(id = userId, address = address)
  }
Now in the main function we can handle the Valid and Invalid with pattern matching and look, we can stop the computation without throwing exceptions, which makes testing and everything way simpler.
Hardly. Erlang and OCaml function in an implicit, ambient monad which makes some default choices like "single thread of execution, sequential, deterministic state, has exceptions" and each will use monads when a different choice of monad is useful.

As a simple example, if you'll buy that by your reasoning OCaml would find monads to be a "useless, redundant abstraction which will only clutter the code", then I'd ask why both Async and Lwt are built to be monadic? Or, if you still feel that's a mistake, how you'd design them elsewise?

It's for being able to write functions that are generic in the context they operate in. You absolutely would want to do this in Erlang, or in SML if the type system supported it.

E.g. I can use Future for managing async-ness. I can use a system a bit like http://typelevel.org/blog/2013/10/18/treelog.html for weaving statistics collection through my computation. I use Free to express database operations that need to happen in a transaction. I can use Either to handle operations that might fail.

I can write a method that builds a report from a bunch of rows that works with any of these four contexts, because all of them form monads.

Many IO functions in Haskell use what is known as "lazy I/O", so no, monads are not particularly to do with order of evaluation.

http://book.realworldhaskell.org/read/io.html#io.lazy

Do notation.

Haskell's do notation is syntactic sugar over monads which effectively allows you to write 'imperative-looking' code while still carrying a local state forward without mutation. The Wikibook[1] does a pretty good example of explaining what this looks like (though I'm guessing you already know this).

Now, obviously it is true that one of do notation's advantages is the same as any other monad usage: it allows us to explicitly sequence events in a lazy language that otherwise offers no (obviously intuitive) guarantees on evaluation order. In that sense it's nothing more than sugaring over the otherwise necessary usage of a lot of ugly >> and >>= operators everywhere in increasingly annoying indentation.

But the other thing it offers is a syntactic sugaring over carrying state forward into successive computations (like the State monad[2]), which still carries at least some useful sweetness in a language that is otherwise functionally pure, which is why F# generalized the concept even further to computation expressions[3].

Looked at another way, do notation, or something like it, can be used to sugar over something that rather more looks like the Clojure ->/->> operators, where the initial value is essentially a local namespace. Much like the threading macros, the result even appears to be doing a kind of mutation, even though it's actually doing nothing of the sort.

This kind of thing turns out to be useful for games, for instance, as the linked State monad example above does. In games we often have a main update loop, where we have to do several successive operations on our game that might change the state. We can do this a number of ways, but one way is with something like do notation, where for instance (in some hypothetical language) we might do this:

  do with gameState
    oldGame <- gameState
    gameState <- checkInput
    gameState <- tick
    if gameState != oldGame
      draw
And all of this kind of "fake mutation" can be handled underneath the sugar in a purely functional manner. It's something I've been meaning to put into Heresy for some time. Heresy uses continuation based loops that have a "carry value", that can be passed from one cycle to the next. It's a simple matter of some macro magic to then layer over this some syntax sugar that makes that carry value effectively a name space, that can be altered from one statement to the next, but all entirely without actual mutation underneath.

You can write whole imperative, mutation-riddled languages in purely functional ones this way. There's an implementation of BASIC that runs in the Haskell do notation.[4]

[1] https://en.wikibooks.org/wiki/Haskell/do_notation [2] https://wiki.haskell.org/State_Monad [3] http://tomasp.net/blog/2013/computation-zoo-padl/ [4] http://augustss.blogspot.fi/2009/02/is-haskell-fast-lets-do-...

We've leaned on this functional JS library to make JS more type safe (https://github.com/plaid/sanctuary). Heavily borrows Monads and other FP concepts.
Very powerful addition to JS. Definitely using this in my next project.
Here's a thing I wrote when this was submitted to Lobste.rs: an implementation of the continuation monad which was elided.

https://lobste.rs/s/r5oeqr/monads_in_javascript/comments/sxt...

Am I crazy that I never understood the point of talking about monads? It just seems like a trivial pattern. It's like having a Subroutine Pattern, or a Variable Assignment Pattern. I'm all for investing in better primitives, but do these kinds of libraries really help vs implementing them from scratch with language primitives inside your (inevitably more complex) domain code?
The big problem with monad tutorials is that you can't talk about them without understanding the motivation behind them, and that comes from purely functional languages (i.e. Haskell). When you're not allowed to touch IO, use `null`, exceptions don't exist, there is no global state, and all of these things have a common pattern to them, then you can motivate their use and talk about them. In my opinion, there isn't much of a point in talking about them without those things. There are some neat tricks (`flatMap` etc...) but without proper motivation, it's not likely to stick, and the idea seems relatively useless.
> It just seems like a trivial pattern.

It is a trivial pattern. But a powerful one.

> I'm all for investing in better primitives, but do these kinds of libraries really help vs implementing them from scratch with language primitives inside your (inevitably more complex) domain code?

Yes - the best way to build complex things is out of simple primitives. A lot of the time, making a custom type be a monad simplifies the logic - that is, you'd want to implement the monad operations (and support do notation) anyway. Calling them by their standard names makes it easier for other people to read your code, and being able to use generic library functions like traverse (which work for any monad) with your custom type is just a bonus.

I suppose it's nice to have a bunch of generic monad functions already implemented for you. Stuff like do-notation, applicative, sequence, mapM, join, etc.
Not crazy, I wish people would take monads off the pedestal.
Taking that (free) class on coursera was an eye opener on all the things that are discussed in this article. Highly recommended:

https://www.coursera.org/course/reactive

This looks awesome. I wish there was way to watch the videos of the course.
Love Javascript and want to learn FP? Checkout this book - https://github.com/DrBoolean/mostly-adequate-guide.

I stumbled upon it last week and I've found it to be quite approachable (although I haven't yet read the section on Monads).

I've really enjoyed "Functional JavaScript - Introducing Functional Programming with Underscore.js". I almost didn't get it because the use of underscore was a bit of a concern (the library is great but I felt I wanted to learn FP with "pure" JS). It was a fairly big step up from the intro to JS I read before (Eloquent JS) but it's a fantastic book. Jam packed with good stuff. I think the writing is a bit dense at times but the content is gold.
search in repository + pattern matching --> no results

:(

I came to an understanding of monads the other day thinking about fail-and-reverse-on-error applications like messing with the filesystem. I have an example of this (and a simple implementation in OCaml) if it helps you [0]. After my "breakthrough", I've been seeing monads everywhere; everything is a nail.

[0] https://github.com/eatonphil/monad

In a strict (as opposed to lazy) non-functional language monads make no sense. Write two statements which uses a temp variable on the same line, separated by a semicolon - this is your monad.
No way. While I do agree monads don't make sense in some imperative languages, writing two statements on the same line is not a monad.
I recently grokked monads, only to realize that monads are just a special case of something more general called arrows. waah.
Well, those are some fancy ligatures.

Wonder why the author enabled st but not ct, though...