Naming is one area where Haskell's academic background is more curse than blessing. Numerous tutorials and blog posts would never have been written if only functor was named mappable and monad was named computation builder. They're named by analogy to category theory, but their usage in computer science is not at all similar.
The Haskell monad typeclass _is_ (modulo technical details) a category-theoretic monad on the category `Hask`.
As Edward Kmett says in more detail in [1] - the point of calling a monad a monad is not to confuse the reader, but to unlock 70 years of documentation on the concept for the reader. How many programming concepts/tools/libraries do you use that have 70 years of documentation?
Being abstract is profoundly different from being vague.
How is the list monad a "computation builder"? Sounds to me like "programmable semicolons" and other nonsense: Monad is a typeclass that means very different things depending on what type you're using. It's the shape that has meaning: this level of abstraction is just going to be hard to grasp correctly no matter what you call it.
Likewise with "Mappable": in most other languages, `map` is only an operation on lists or list-like things. `ask` in `Reader` is implementable with Functor only: by what tortured metaphor does `Mappable` help you understand that? Also it sounds like Java. Yuck :)
Names are a bikeshed. Monad, Applicative and Functor have the advantage of at least being rigorous, I can't see any other name being better.
Their usage in Haskell/OCaml etc is precisely faithful to their category theoretic definitions as can be in a general purpose language.
This debate about naming monads is pretty tiresome after so many years, if one called it "computation builder" it wouldn't change their structure or convey any notion of the laws any better than term monad. A monad at it's core is a set of algebraic relations.
There are some major benefits to the Haskell community's approach of naming abstractions after the math (where a suitable mathematical abstraction exists).
First, as has been mentioned, there are existing treatments of the objects in question, some interesting results there can be ported over to programming, and intuitions there lead new and sometimes useful places. Some newcomers will even be familiar with the concepts already - this is very few people for monad, but far more for monoid and semigroup.
It avoids erecting an unnecessary wall between programming knowledge and mathematical knowledge.
Second, it changes the character of a particular kind of discussion: there is never ambiguity about whether a newly considered operation on a type "really" is "appending" - is it associative? does it have an identity? you've got a monoid. This means it's very clear what you can and cannot assume around a particular interface. Questions about whether "functors" are well thought of as "containers" or "mappable" or whatnot are clearly only questions of pedagogy.
The monads that were harder for me to understand while learning Haskell had quite plain names like "State" and "Continuation". I don't think alternative naming would have helped.
By the way, while I'm not sure the monad concept would be useful for all languages, I believe monoid really should become common parlance. It's such a simple and useful idea.
A decent indication that it's not as simple as "well just call it x instead" is that each time I see a comment like this there is often a new "easy" word for monad. Yours is new to me, so I'll add it to the list:
Their naming is similar enough to leverage existing research literature, and knowledge, though. Those with a background in math can map some of their existing knowledge. Those without a math background have a more precise vocabulary to understand the concepts and research further. Even if they are a bit foreign, I prefer the attempt to be precise.
My problem wasn't the word but the fact that the word is not adjective - originally I spent a lot of time thinking "where is the monad?". This of course is the wrong question to ask, but if the word was "monadic" instead, then I would've known that this is a property (like iterable, foldable, applicative etc), and realized I should think of typeclasses more in terms of interfaces rather than values.
Sure, their instances (implementations) are values (dictionaries of functions which are implicitly passed around) but thats beside the point when learning.
Yeah, the Haskell culture seems to have a problem with naming. It uses a lot of mathematical terms and a lot of alphabet soup identifiers. Part of the problem is just that naming highly abstract things is hard (what would be a meaningful name for the monadic return operation?) Another part is that the commercial programming world has developed a whole art of naming things so that a maintenance programmer can understand them easily, but the Haskell community doesn't want to use that art because it reminds them of Java or something.
Something I've wondered about: How does Haskell not optimize away IO ()? In a pure, functional languages, a function that doesn't return anything can simply be eliminated — but of course it isn't.
I've always assumed that Haskell's compiler has a built-in rules about IO having side effects, but I never actually bothered to find out.
When I first started with Haskell, one of many small epiphanies was when I realized that the IO monad itself doesn't actually do anything. bind and return don't do anything except wrap and unwrap values, and there's nothing that checks if you are in some kind of "IO context" to permit things like file I/O. There's no magical "side-effectful computation chain engine" behind the scenes.
IO is the type, not the value. Something that takes IO and returns IO wouldn't be optimized out for the same reason a negation wouldn't be optimized out simply because it takes an Int and returns an Int.
"We can see therefore how Monad offers strictly more powerful transformations than Functor. fmap can only transform an individual value “in place”, while >>= can return an empty list, or a list with more elements than the original. Functor is “structure preserving”, while Monad is “structure transforming”."
So for a list monad
bind = flatMap
fmap = map
is that correct?
Studying FP for quite a while first monad tutorial I come to fully understand finally.
So is it possible to explain monads with Javascript ? or even LISP ? seems to me monads == haskell so if one doesn't understand haskell one can't understand monads , cause all monad tutorials are written in haskell. So I ask , what is the point of learning what a monad is if i'm writing some Java ?
Yes. Infact, a JavaScript Promise is pretty much the same as the IO monad* - the `then` method is a lot like `bind`. Promise.resolve is a lot like `return`
* almost the same to IO, because of recursive thenable assimilation, something that was added to promises but is totally short-sighted and unnecessary; and because promises are eager which means they don't represent the action to be executed, but the value of an already executed action
It is possible to implement monad-like behavior in javascript. But javascript does not have a type system to model them in.
Haskell is great because it's type system is rich enough to represent these concepts and not only that but enforce their usage (to a degree). Unfortunately this is like a drug, once you get a good dose of Haskell it's easy to crave an even richer type system with dependent types.
For one example, Scala's `for` syntax is quite similar to Haskell's `do` notation, and lets you do some monadic things with `Option`, `Seq`, and other classes.
And then you can go much further into that world with the scalaz library.
[+] [-] nilved|10 years ago|reply
[+] [-] ajtulloch|10 years ago|reply
As Edward Kmett says in more detail in [1] - the point of calling a monad a monad is not to confuse the reader, but to unlock 70 years of documentation on the concept for the reader. How many programming concepts/tools/libraries do you use that have 70 years of documentation?
Being abstract is profoundly different from being vague.
[1]: https://yow.eventer.com/yow-2014-1222/stop-treading-water-le... (around the 20 minute mark).
[+] [-] spopejoy|10 years ago|reply
Likewise with "Mappable": in most other languages, `map` is only an operation on lists or list-like things. `ask` in `Reader` is implementable with Functor only: by what tortured metaphor does `Mappable` help you understand that? Also it sounds like Java. Yuck :)
Names are a bikeshed. Monad, Applicative and Functor have the advantage of at least being rigorous, I can't see any other name being better.
[+] [-] freyrs3|10 years ago|reply
This debate about naming monads is pretty tiresome after so many years, if one called it "computation builder" it wouldn't change their structure or convey any notion of the laws any better than term monad. A monad at it's core is a set of algebraic relations.
[+] [-] tome|10 years ago|reply
If that were so, monad and functor tutorials would be as follows:
Functor tutorial: imagine it's called "mappable". End of tutorial.
Monad tutoral: imagine it's called "computation builder". End of tutorial
[+] [-] dllthomas|10 years ago|reply
There are some major benefits to the Haskell community's approach of naming abstractions after the math (where a suitable mathematical abstraction exists).
First, as has been mentioned, there are existing treatments of the objects in question, some interesting results there can be ported over to programming, and intuitions there lead new and sometimes useful places. Some newcomers will even be familiar with the concepts already - this is very few people for monad, but far more for monoid and semigroup. It avoids erecting an unnecessary wall between programming knowledge and mathematical knowledge.
Second, it changes the character of a particular kind of discussion: there is never ambiguity about whether a newly considered operation on a type "really" is "appending" - is it associative? does it have an identity? you've got a monoid. This means it's very clear what you can and cannot assume around a particular interface. Questions about whether "functors" are well thought of as "containers" or "mappable" or whatnot are clearly only questions of pedagogy.
[+] [-] danidiaz|10 years ago|reply
By the way, while I'm not sure the monad concept would be useful for all languages, I believe monoid really should become common parlance. It's such a simple and useful idea.
[+] [-] wetmore|10 years ago|reply
Monads are hard, let's call them
- FlatMappable
- AndThenable
- Joinable
- Chainable (or, Daisychain)
- Computation Builder
[+] [-] creichert|10 years ago|reply
[+] [-] spion|10 years ago|reply
Sure, their instances (implementations) are values (dictionaries of functions which are implicitly passed around) but thats beside the point when learning.
[+] [-] cousin_it|10 years ago|reply
[+] [-] imh|10 years ago|reply
http://slpopejoy.github.io/posts/Effectful02.html
[+] [-] bshimmin|10 years ago|reply
[+] [-] spopejoy|10 years ago|reply
[+] [-] unknown|10 years ago|reply
[deleted]
[+] [-] jtaylor100|10 years ago|reply
[+] [-] lobster_johnson|10 years ago|reply
I've always assumed that Haskell's compiler has a built-in rules about IO having side effects, but I never actually bothered to find out.
When I first started with Haskell, one of many small epiphanies was when I realized that the IO monad itself doesn't actually do anything. bind and return don't do anything except wrap and unwrap values, and there's nothing that checks if you are in some kind of "IO context" to permit things like file I/O. There's no magical "side-effectful computation chain engine" behind the scenes.
[+] [-] erydo|10 years ago|reply
[+] [-] heroku|10 years ago|reply
So for a list monad bind = flatMap fmap = map
is that correct?
Studying FP for quite a while first monad tutorial I come to fully understand finally.
[+] [-] chriswarbo|10 years ago|reply
> is that correct?
Yes, although Haskell calls "flatMap" "concatMap". Of course "return" is just "\x -> [x]", AKA "(: [])".
Instead of bind (">>="), you can implement Monads using "join" instead. For lists, "join" is simply "concat".
[+] [-] aikah|10 years ago|reply
[+] [-] spion|10 years ago|reply
* almost the same to IO, because of recursive thenable assimilation, something that was added to promises but is totally short-sighted and unnecessary; and because promises are eager which means they don't represent the action to be executed, but the value of an already executed action
[+] [-] nightski|10 years ago|reply
Haskell is great because it's type system is rich enough to represent these concepts and not only that but enforce their usage (to a degree). Unfortunately this is like a drug, once you get a good dose of Haskell it's easy to crave an even richer type system with dependent types.
[+] [-] andrus|10 years ago|reply
https://github.com/fantasyland/fantasy-land
[+] [-] unknown|10 years ago|reply
[deleted]
[+] [-] kilovoltaire|10 years ago|reply
And then you can go much further into that world with the scalaz library.
[+] [-] danidiaz|10 years ago|reply
[+] [-] agumonkey|10 years ago|reply
https://www.google.fr/search?q=jvtoups+monads
I hope you know lisp just enough to adapt to the lisp-1 lisp-2 namespace.
[+] [-] unknown|10 years ago|reply
[deleted]