Monads Are Not Metaphors (2010)
codecommit.com
codecommit.com
Label a concept "this is just engineering practice" or "this is just physics. this equation describes how universe works" and people will happily accept it as is.
But label it "mathematics" and explanations are in order because maths is hard to understand...
I don't see any posts where authors concern themselves with metaphors for Maxwell's equations (or anything else in physics; maybe I'm hanging out in the wrong circles though).
What is a process of understanding a mathematical equation? Stare at it until you grok it? Use it to solve problems to get a feel of what it means? Write proofs about it so you can state some properties with certainty?
I don't know what the best/structured process is, but the core is "take this equation and do something with it".
Do the same with monads! I think people having problems understanding monads are those that defer writing any code until they feel "they get it". Instead of "now I get it, monads are burritos, time to write some code" one should write some code in order to understand monads
The complaint was that those problems where incomprehensible gibberish and kids and adults alike had really hard time figuring them out.
From what I recall the core of the issue was that the question authors had some specific mental model of how addition and multiplication works and the questions were structured in a way that required figuring out what that model was (otherwise it was very hard to understand what was being asked).
Why does 2 + 3 = 5? Well, because it does. I don't even know what my mental model of addition is. I just do it. I stared at it long enough as a kid and I developed neural circuits that compute the result.
Instead if I asked:
I have two stars in a box. How many squares do I have to put in the box to have 5 shapes?
| * * | + | ??? | = | * * # # # |
Which is how I recall those weird maths questions were structured.Now you a have a (terrible IMHO) model of addition. That's what I think those monad tutorials do for you.
Those monad metaphors provide the same benefit. Even if some intuitions are wrong and you still need to learn the match to get the whole picture, at least you get a sense of (partial) understanding and purpose during the whole learning process thanks to the metaphor, instead of feeling lost the whole time.
Yes.
https://www.maa.org/external_archive/devlin/LockhartsLament....
(A frequent HN link, but, well, for good reason.)
Read page 16+17 and tell me who you agree with more, SIMPLICIO or SALVIATI
The irony is that even in painting, there is a fair amount of "rote" or repetition needed before ones "creativity" can be explored.
This may be somewhat tangential/distracting, but I find the whole notion of 'creativity' problematic - many artists also think so (“Amateurs look for inspiration; the rest of us just get up and go to work.” ― Chuck Close).
What I learned in elementary school is OK. (There my objections would center more around the cohort system being terrible, but that's another objection. Also, I have to qualify that because the education system considers screwing with elementary math education one of their primary mandates.) But math education flings itself off the rails when it starts doing symbolic manipulation. (And if anything, every time they screw with it they're flinging themselves off the rails harder and sooner.)
I won't say it better than in this post![1] It's really too bad that people in general are struggling with the different problems related to Mathematics, or because they don't have a good environment to learn, or other things like that.
The thing is when someone starts to learn Mathematics, the beginning is really tough. You have a new language to learn, you have to do everything the "hard way", you have to learn the "handshakes", and because your mind is your only compiler/error check. But the longer you train yourself the better you get, until you have enough basic knowledge to read and learn anything. At the end it is so grateful to overcome that, and so useful because Mathematics is such a powerful tool.
[1] http://jeremykun.com/2013/02/08/why-there-is-no-hitchhikers-...
Using Monads in a programming context teaches you how to use monads in a programming context.
This is quantum mechanics through and through. While the equations are agreed on, interpretations vary and you get weird varied metaphors all over the place.
There is no reason at all that a straight-A high school math student should be expected to be even slightly good at writing proofs.
Compared to programming (even functional), "math" is a completely different way of thinking. Abstract properties are stated, from which some arbitrary (partial) structure is implied. Whereas with programming, the structure of "doing" is always concrete, regardless of paradigm (algorithmic complexity is everpresent, even when you're ignoring it). Compared to abstract math, school classes are more akin to programming in that you're mostly following algorithms and applying patterns with a slight intuition, even when you get into algebra and calculus.
My biggest hurdle to understanding is the use of completely different terminology for concepts that are the same, at least intuition wise. My thought process is based on intuitions first, rather than manipulating symbols in the abstract (which seems to be more common? or maybe it just seems this way?). So when confronted with terms like 'conjunction' and 'disjunction', it just throws me off that they're 1. the "same" as AND/OR, 2. the nuance of difference is rarely stated. So the way I cope is by directly thinking AND/OR, while being painfully aware that there is some distinction I'm not aware of. This leads to a lot of reading that's completely disconnected from anything until I find the gem that illustrates the actual difference.
I'd learned the workings of practical Haskell monads some time ago, but what made monads/category theory finally click is reading Moggi's "Notions of computation and monads". Going back to the "source" let me see the specific motivation and actually understand how Haskell objects differ from perfect ones from category theory. Apparently it's just non-termination, but I had to do a lot of searching to find where that was actually stated, rather than assumed and vaguely referenced. It feels like to someone who thinks "more mathematically" this is just a small detail, since they deal with each type of structure in isolation. But until I can relate them, I'm just out in the weeds.
Of course now that I understand this it seems like quite a simple concept. But I had to do an awful lot of work to get to the point where my thought gamut was "expanded" to be able to include this one concept.
So I don't really know what my exact point is. But to connect to something you said, it seems like experience from writing code and desire to understand abstract concepts ("monads are burritos") come from two different places, and the latter isn't necessarily served by increasingly outlandish metaphors, but by making the details accessibly explicit.
I greatly benefited from the "conveyor belt" metaphor for learning monads; it made me grasp instantly something that I would have never understood from a pure theoretical explanation - namely why they are so useful and widespread in functional programming, as a building tool to distribute logic among several composable functions over a data type. Sentences like "We start with one thing and use its value to compute a new thing" and "Monads are an abstract, mathematical label affixed to a pattern found in almost all code" will never convey information about how it's intended to be used in the same vivid way as the metaphor.
I know for true that the pure mathematical approach leaves me hanging. I learned linear algebra in the theorem-proof style, and as of today I still don't know when it's an adequate technique to use. I can't tell what matrix ranks, kernels or tensors are good for even though I can calculate their values very precisely.
Thanks for that! Here's a link:
http://web.archive.org/web/20100910074354/http://www.haskell...
Also is there anyone here who understands what monads are but has never programmed in haskell or a functional language?
If the OP really wanted to make this a better introduction, they really needed to slow down, use pseudo code with lots of explanations of the concept of "and then".
That is hilarious:
note: the andThen method isn’t defined for functions of 0-arity, but we’re going to pretend that it is and that it works the same as it does for functions of one argument.
Here's this thing that no one who doesn't already understand monads has ever seen, and that actually doesn't even work in this situation, but let's pretend it has some other definition that would work, if that were actually possible, which isn't the case. Why is everyone running, screaming, back to metaphor-based tutorials?
The attempts to introduce monads in other languages like Python, Ruby etc. is missing what make them a useful tool in Haskell.
Hell, JavaScript promises are basically a bastardized and slightly inconsistent monad, and they're still useful even without syntax sugar. If we could generalize over the API and use them for other things it would be even better, but that's not the JavaScript way.
The .then method is bind. Or it would be if they didn't automatically flatten nested promises. Since they do, then is a hybrid of map and bind that doesn't quite cover the use cases for both.
While I agree that the syntactic sugar of the "do" notation in Haskell makes Monads vastly more useful, there are examples where Monads have been applied in other programming languages without any syntactic sugar.
For example, there are parser combinator libraries (influenced by Parsec) in many languages. E.g. Python's pyparsec is internally using monads that are defined just as they are in Haskell.
Monads are a great idea for many practical tasks in programming, their use in Haskell is often emphasized becuse they're required for IO (which is not the case for imperative languages). For many of the non-IO applications of monads, they're just as useful in other languages too.
Monads can be understood very simply in Category Theory if you don't care so much about the details: pick a couple of your favorite categories (which is just a bunch of objects with morphisms) and find a functor between them. Then find a functor back the other way. Composing those two functors gives a Monad - a functor from a category back into itself (an endofunctor). Not just any endofunctor will be a Monad though, so if you start with an endofunctor (instead of two functors) you need to also have two other "natural transformations". (That endofunctor + the two natural transformations is why monads are sometimes called triples).
The application of monads to programming was not obvious to me, even having dealt with them a bit mathematically. I started looking at Haskell earlier this year and it turns out that a Monad in haskell is defined on the Hask category, where objects are types and morphisms are functions between them. Even that wasn't enough for me to get why they're useful, and that seems to be because as far as I can tell they're only used for "threading" state through a series of functions...but perhaps I'm still missing something?
That is why people bump up against them when learning Haskell, but monads run much deeper in functional programming.. Even "pure" functions in Haskell are monadic with respect to the non-terminating "bottom".
I said it elsewhere in this topic, but check out Moggi's "Notions of computation and monads".
Monads don't necessarily have anything to do with sequencing or computation, and the author is objectively incorrect to say "monads are a pattern, not a specific type". In fact, monads are an algebraic structure, defined only by the types of the operations defined on them and the laws those operations obey.
That's not to say that concrete examples like the one here aren't useful, but the author is not covering the full scope of what monads are.
I've tried reading (but not coding), and all I hear is sequence of operations, chaining, and similar. I know I'm missing something.
Basically I haven't seen or synthesized the tl;dr that makes me want to learn a language that has them.
As far as other uses: The best explanation that I've seen is that they let you hide the parts that you need to do, but that aren't the real thing your doing. Logging, for instance. You can add logging to something, and just string functions together as if there were no logging going on. (Of course, if you were doing non-pure-functional programming, you could just add logging statements wherever you wanted, and string your functions together just the same...)
You can check out this module:
http://hackage.haskell.org/package/base-4.8.1.0/docs/Control...
You can see all the varied sorts of things which are "instances of Monad", then scroll beyond and see all these different useful operations which behave sensibly for all those different instances (and from which you can build your own more complex operations which work for any Monad, and which also behave sensibly).
"All useful languages have monads ... nearly impossible to avoid."
So here's a post on Python (hopefully useful) and monads, it appears to be implementing a pattern, although I don't think I would have ever stumbled across it naturally.
http://www.valuedlessons.com/2008/01/monads-in-python-with-n...
And here's a library implementing monads and other stuff:
https://pypi.python.org/pypi/PyMonad/
It still looks like I'm going to have to try using them before I can figure out if it's worth trying to use them.
For instance in C#, there is a monad with bind=?? and return=no-op (similar in use to the Maybe monad in Haskell). There's another monad with bind=; and return=no-op (similar in use to the IO monad in Haskell). C# just doesn't explicitly recognize those as monads.
I think mode C# programmers would likely think of ';' and '??' as syntax, and who is thinking of 'no-op' as anything!?
But if you were in haskell this would not be syntax, but just functions on an instance of the Monad type class.
Haskell could easily add some sugar to make these constructs syntax as well, but it would just be sugar -- and that is where the power, and confusion I think arises when most programmers think about monads.
I desagree. While it's true that metaphors can be over-stretched and cause problems later, a well-placed metaphor at the beginning of the learning process can do wonders to quickstart understanding of a topic about which you know nothing at all.
At the very least, the metaphor will provide meaning to the very act of learning, explaining why you should bother at all with that topic. Experts explaining their subject often forget what it's like to not know how two concepts in their domain relate to each other and the uncertainty when reading a sentence that connects them in a way that has not been seen yet.