If this is all there is to monads the functional community needs to level up their communication experience and/or allow themselves to stop talking in terms of type theory.
Edward talks about the monad laws, especially the associativity one. But that is kind of simplistic, because the domain over which the laws apply can be shaped quite complexly, leading, for example, to IO or State being "monads". I fail to see how the associativity law is very useful in reasoning about IO / State. All I can see is that, syntactically, the parse tree (a; b;) c; executes the same as a; (b; c;) under a left-most evaulation rule.
Duh, blocks are evaluated in leftmost order. This is neither news, nor particularly profound in any number of popular curly brace languages. Rewritten with curly braces, so it's recognizable by most Blub programmers out there:
The distinction is not important in an eagerly evaluating language, which steps through its statements one by one and executes them as it finds them.
In a lazy, pure language it is of very great importance! With lazy evaluation you get no guarantees as to what order your expressions are evaluated in. Statements like "Blocks are evaluated in leftmost order" are just false in Haskell.
Monads give you the ability to sequence your I/O actions even though they are still lazily evaluated. This is why Haskell needs monads, and most other languages get by without them.
Another way to think of it is that monads are embedded into the operational semantics of eager languages, so you that the programmer doesn't need to be aware of them. After all, monads were initially used to formally describe the behaviour of ML, an eager language, before they were used in Haskell.
As he points out in his introduction, the first rule of monads is that everyone else's description of monads is wrong.
It appears that all you can do is share the mathematical description of a monad (and not the way it is declared in Haskell which also appears to be universally accepted to be wrong). All further abstraction, description, and communication are approximately equivalent to debates on religion.
I have a deep suspicion that this quality makes Haskell essentially write-only at scale.
I'm not quite sure what you mean: monads are very well defined even within Haskell, certainly more than most programming abstractions. Essentially, a monad is any type that has some particular functions defined on it that act consistently with each other (e.g. follow the monad laws). That is all a monad is--understanding what they're useful for or why we care is a different story, but you can get that from examples.
You can have a perfectly good grasp of monads in Haskell without understanding the mathematics behind it at all: the a look at the "you could have invented monads"[1] tutorial.
Moreover, the behavior of monads is more precisely proscribed than the behavior of abstractions used in other languages. While you do not need to understand the mathematical background to use monads, the fact that's it's there helps ensure that implementations act consistently. Having explicit laws implementations must follow makes it much easier to rely on them.
So monads are actually very well defined, even if too many people rush out to write ill-advised blog posts before they actually understand anything (this post is a great example, as is the linked talk by Douglas Crockford).
Ultimately, I think Haskell is the language that works best at scale. It both gives you the tools you need to write extremely maintainable code and also actively encourages you to do that. I've found Haskell code to be significantly simpler, more self-contained, more decoupled and more self-documenting than any other language I've used. I've found it far easier to come back to Haskell code I left months ago than to come back to Python out JavaScript or Java code, by a fair margin.
> Ultimately, I think Haskell is the language that works best at scale.
While i agree on that, i think it depends on what one means with "at scale". I've seen that phrase used to mean something like "having a humongous team of 50+ developers and being able to add 50+ new (preferably cheap) developers (who might not be very well versed in the technology nor the business that we're working on) at any time and make them write code right out of the bat". I think Haskell would not fit very well with that "work at scale" definition :)
This is a vast oversimplification of both Haskell's monads and the category theoretic Monad. Just because you can chain methods doesn't make something a Monad even in the most basic sense of satisfying the typeclass requirements in Haskell.
It does not cover any of the interesting traits of Monads.
I could try to explain Monads in this comment, but others have already done it well.
Any explanation of Monads must at least cover the actual Monadic operations and the laws that relate them. Also, all of the examples he brings are not actually Monads, as explained by others.
> Any explanation of Monads must at least cover the actual Monadic operations and the laws that relate them. Also, all of the examples he brings are not actually Monads, as explained by others.
That's not true at all, and thinking like that is the reason why so many awful monad tutorials exist, and everybody outside of the Haskell community immediately tl;dr's when monads are mentioned.
You don't need to understand the monad laws to use monads. You do need to understand the monad laws implement your own monad. They are two completely different levels of understanding, and there's nothing wrong with that.
I respectfully disagree. It wasn't until I read the typeclassopedia and the article on the Haskell category (that goes into the Monad laws, the Functor laws, &c...) extensively did I really start to understand Monads.
At first, reading all of these "tuts" or "analogies" I always thought, "Oh! It's just like an object in Python!" but boy was I wrong - no one told me I was wrong, I just figured it out after reading the more formal presentations of what a Monad is.
It was also mind opening to understand the basics of Category Theory and learn that every Monad is a Functor.
He wasn't trying to explain how to use monads. There are good tutorials that do that. He was trying to explain what they are. And that definitely involves their operations and the laws that apply.
I don't fully understand monads, but this is disingenuous. The article clearly compares unit to constructors, in a way that is far more like this:
class Monad:
def __init__(self, val):
self.val = val
unit = __init__
def bind(self, fun):
return fun(self.val)
Now, in the case of our ruby and python examples respectively, there is no sane way of enforcing typing, but if it works out, it looks to me like that at least implements the monad interface. Not so sure how all the laws work out...
But interestingly we could implement lift as a Monad method by:
> A Monad is an object whose methods return monads.
Further down, it explicitly states that this is not an analogy, that it is 'equivalent':
> That is, that the following definition is equivalent
> to the type theoretical definition of monads:
My Monad object has one (actually... let's not go there yet) method, and it returns a Monad. I happened to name it 'unit' but it could have been 'foo' and it would still fall under the definition given in the article. I've edited my above post to change the name.
Okay, now let's go there: another reason that this is even more silly is that my object has way more than one method:
irb(main):005:0> Monad.new.methods.count
=> 57
Many of these do not return a monad. Even if I inherited from BasicObject, there would be methods that do not return a Monad, and therefore, according to the above definition, it is impossible to have a monad in Ruby. However, you can have a monad in Ruby, so this further demonstrates that the above definition is incorrect.
These "monad tutorials" drive me nuts. I wasted a week trying to understand monads from random "You can do monads in Python, JavaScript and Brainfuck!" tutorials that all had different (and sometimes inconsistent) perspectives on what they were and what they were good for before I gave up and learned Haskell. In my case, I was laboring under the false assumption that because I knew language X, it would be easier to learn about monads in X than to learn Haskell. In Haskell, the value of monadic computation falls out naturally from the type system and syntax. Yes, you still have to verify the laws, but Haskell's purity makes this easier as well.
I think the jQuery analogy has some didactic value for understanding combinators, but calling it a monad and falsely asserting that the laws hold is not doing "normal programmers" any favors. In the comments, he analogizes demonstrating the map function to C programmers, but this analogy is false because he clearly understands map and what it's used for but the same cannot be said for his understanding of monads.
For "normal programmers" out there who want to (for whatever reason) learn about monads, my recommendation is to ignore these tutorials and learn Haskell or an equivalent. I learned Haskell specifically to develop an understanding of monads, but what I got out of it was much, much more valuable than just an understanding of monads.
Having used them I came to the conclusion that the monad itself is just not a useful concept; it's only when you're trying to do something that it makes sense. I tried to write up my experiences as http://m50d.github.com/2013/01/16/generic-contexts.html (very scala-oriented), would be interested to hear whether that's useful to anyone.
Yes, that is a much better explanation of Monads. My experiences mirror yours. Monads didn't make sense to me, while at the same time I was happily using option and future and thinking how cool it was I could nest flatmap calls by using the for syntax. Then one day.....
Couldn't agree more. I read somewhere (I forget where): "You don't need to learn Category Theory in order to learn Haskell. Learn Haskell, and you'll develop an intuition for Category Theory as a side-effect."
I think the best "Monad tutorial" is Learn You A Haskell For Great Good[1], in its entirety.
Craft of Christ, jQuery is not a monad. Ever since the first disgraceful post to that effect, people have been spreading this utterly false rumor and confusing the people they are supposed to be teaching.
Uh, these are not monads. These are actually what we might call "wrappers". They just provide a nicer interface for an underlying API (the DOM in jQuery's case, and sql queries in Django's).
What is a monad is JQuery.Deferred, with the `.then(...)` method as the `bind` operator. This has to be monadic, because it wraps a promise of a value that can't be computed synchronously.
It is similar to a Monad, but not quite, because the "bind" (addCallback) mutates it inplace, and does not return a chained operation. Also because if your callback's return value is itself again a Deferred, it will flatten it out. That means it "auto-joins" on the result so if you want to actually result in some Deferred object in your callback you have to wrap it to circumvent the flattening.
A monad is an object whose methods return:
either itself if that method is not meant to change the object's properties, like getters;
or a new copy of original monad object with changed properties if that method is meant to change object properties, like setters.
A monoid is anything with an associative append and an identity operation. A monad is a form of monoid (in the category of endofunctors; what's the problem?), but monoids are not necessarily monads.
> A monoid is anything with an associative append and an identity operation.
It doesn't have to be an append, it can be any associative operation that is closed over its domain and the domain features an identitiy element.
> A monad is a form of monoid (in the category of endofunctors; what's the problem?),
A category theoretic monad may be a "monoid in the category of endofunctors". The Monad type is not, strictly speaking, a monoid (but looks like one if you squint a little).
I think that monad is actually the "." in the OO world. This is because in my view the monad actually sits in between the functions and controls the function combinations and the value between the threading. So for instance Maybe will decide whether to really call the next method based on the value itself (like null). Or I maybe wrong :)
46 comments
[ 2.7 ms ] story [ 96.3 ms ] threadhttp://blog.jorgenschaefer.de/2013/01/monads-for-normal-prog...
http://blog.jorgenschaefer.de/2013/01/monads-for-normal-prog...
In a lazy, pure language it is of very great importance! With lazy evaluation you get no guarantees as to what order your expressions are evaluated in. Statements like "Blocks are evaluated in leftmost order" are just false in Haskell.
Monads give you the ability to sequence your I/O actions even though they are still lazily evaluated. This is why Haskell needs monads, and most other languages get by without them.
Is a truly terrible "definition". It is not a constructive definition. You can't implement anything with this.
Mostly this article is about combinator libraries -- where bind is function application. Nothing to do with monadic bind.
It appears that all you can do is share the mathematical description of a monad (and not the way it is declared in Haskell which also appears to be universally accepted to be wrong). All further abstraction, description, and communication are approximately equivalent to debates on religion.
I have a deep suspicion that this quality makes Haskell essentially write-only at scale.
You can have a perfectly good grasp of monads in Haskell without understanding the mathematics behind it at all: the a look at the "you could have invented monads"[1] tutorial.
[1]: http://blog.sigfpe.com/2006/08/you-could-have-invented-monad...
Moreover, the behavior of monads is more precisely proscribed than the behavior of abstractions used in other languages. While you do not need to understand the mathematical background to use monads, the fact that's it's there helps ensure that implementations act consistently. Having explicit laws implementations must follow makes it much easier to rely on them.
So monads are actually very well defined, even if too many people rush out to write ill-advised blog posts before they actually understand anything (this post is a great example, as is the linked talk by Douglas Crockford).
Ultimately, I think Haskell is the language that works best at scale. It both gives you the tools you need to write extremely maintainable code and also actively encourages you to do that. I've found Haskell code to be significantly simpler, more self-contained, more decoupled and more self-documenting than any other language I've used. I've found it far easier to come back to Haskell code I left months ago than to come back to Python out JavaScript or Java code, by a fair margin.
While i agree on that, i think it depends on what one means with "at scale". I've seen that phrase used to mean something like "having a humongous team of 50+ developers and being able to add 50+ new (preferably cheap) developers (who might not be very well versed in the technology nor the business that we're working on) at any time and make them write code right out of the bat". I think Haskell would not fit very well with that "work at scale" definition :)
This is exceptionally wrong.
I could try to explain Monads in this comment, but others have already done it well.
Any explanation of Monads must at least cover the actual Monadic operations and the laws that relate them. Also, all of the examples he brings are not actually Monads, as explained by others.
That's not true at all, and thinking like that is the reason why so many awful monad tutorials exist, and everybody outside of the Haskell community immediately tl;dr's when monads are mentioned.
You don't need to understand the monad laws to use monads. You do need to understand the monad laws implement your own monad. They are two completely different levels of understanding, and there's nothing wrong with that.
At first, reading all of these "tuts" or "analogies" I always thought, "Oh! It's just like an object in Python!" but boy was I wrong - no one told me I was wrong, I just figured it out after reading the more formal presentations of what a Monad is.
It was also mind opening to understand the basics of Category Theory and learn that every Monad is a Functor.
EDIT: s/unit/foo/, to remove discussion about comparisons to the 'unit' that monads actually have.
But interestingly we could implement lift as a Monad method by:
unless I really don't get all this.Okay, now let's go there: another reason that this is even more silly is that my object has way more than one method:
Many of these do not return a monad. Even if I inherited from BasicObject, there would be methods that do not return a Monad, and therefore, according to the above definition, it is impossible to have a monad in Ruby. However, you can have a monad in Ruby, so this further demonstrates that the above definition is incorrect.I think the jQuery analogy has some didactic value for understanding combinators, but calling it a monad and falsely asserting that the laws hold is not doing "normal programmers" any favors. In the comments, he analogizes demonstrating the map function to C programmers, but this analogy is false because he clearly understands map and what it's used for but the same cannot be said for his understanding of monads.
For "normal programmers" out there who want to (for whatever reason) learn about monads, my recommendation is to ignore these tutorials and learn Haskell or an equivalent. I learned Haskell specifically to develop an understanding of monads, but what I got out of it was much, much more valuable than just an understanding of monads.
I think the best "Monad tutorial" is Learn You A Haskell For Great Good[1], in its entirety.
[1]: http://learnyouahaskell.com/
Then most of them start to understand the power of the concept.
(that's only a comment to make looking for these explanations easier.)
Just as the talk he refers to (I've seen it and it's ok)... It's for JavaScript programmers):
https://www.youtube.com/watch?v=b0EF0VTs9Dc
So unless there's a 1-to-1 mapping between "Normal Programmers" and "JavaScript" programmers this title is quite misleading.
Is it "normal" as opposed to "exceptional/enlightened", to "anormal", to "strange". Doesn't compute.
What is a monad is JQuery.Deferred, with the `.then(...)` method as the `bind` operator. This has to be monadic, because it wraps a promise of a value that can't be computed synchronously.
http://en.wikipedia.org/wiki/Monoid
It doesn't have to be an append, it can be any associative operation that is closed over its domain and the domain features an identitiy element.
> A monad is a form of monoid (in the category of endofunctors; what's the problem?),
A category theoretic monad may be a "monoid in the category of endofunctors". The Monad type is not, strictly speaking, a monoid (but looks like one if you squint a little).
> but monoids are not necessarily monads.
Who said they are? :)