Abstraction, intuition, and the “monad tutorial fallacy”
byorgey.wordpress.com
byorgey.wordpress.com
My thought process about those tutorials is always "explain to me why I should care." I get that the problem that Monads try to solve is that functional programming demands that a function always return the same value given the same arguments, and that makes I/O impossible, but you can't write real programs without I/O. So Monads are an attempt to find a loophole.
Well, what if the answer is just that functional programming is just not a good way to write programs in the first place? Sure, functional programming has lots of properties that are appealing, but if you need to do intense mental gymnastics just to get "print 'Hello World'" is it actually worth it?
To me, that is the point from which a "Monad tutorial" should begin, and then provide concrete examples showing that with Monads, sticking with functional programming is better than just giving up and using Python.
I wrote a answer on stackoverflow which tries to explain monads with some practical examples: http://stackoverflow.com/questions/44965/what-is-a-monad#194...
You also do a good job summarizing why IO is hard in Haskell, in that you need to understand a lot about the language to understand how IO works. I guess it's up to the individual to decide whether FP is worth getting past that initial hump.
Clean employs linear logic, that is you can only have one copy of the 'World' in your program. Look at the printing function as an example: It takes your old World and transforms it into a new World, that has something printed to the screen.
Of course such a view of the outside world is quite autistic. But it works as long as you manage to have only one World around in your program.
The IO Monad in Haskell could have been implemented with linear logic. (And in GHC it is, I think.)
More information at http://homepages.inf.ed.ac.uk/wadler/papers/monadsdeclare/mo...
The original papers are surprisingly accessible. I prefer them to the tutorials.
I think people learn different ways. This writer seems to approach the world in the way I do, but I'm not sure everyone is like that. I've had friends who can start of with the abstract and just suck it in. I think there's a correlation with people who can do this with those who can easily remember things 'for the test' at school even if they can't put the knowledge into context.
I've never discovered how to tweak my brain to get it to buffer knowledge like this with a faith that it will be useful in a minute - I find it exhausting and I still don't retain.
I sat down to write a program in iolanguage the other day. Even though I've read lots of tutorials and feel like I know it now, it was very exhausting to connect that with a practice of do this, now do that, etc. I remember a similar feeling when I started java which I overcame by writing a program a day that started off with static void main(String args[]).
A big hurdle with conceptual ideas is getting your brain to twist the right way around to them when you encounter a problem that could be solved by them. I think this is the difference between raw knowledge and what Heinlein used the word 'groking' to describe.
One game that sometimes works as an alternative is to example-based learning something through a context of documenting it. This can be difficult though if the barrier between this knowledge and other topics isn't well-defined.
I think the solution is to realize that you dont need to understand monads to write IO code, you just need to understand the rules of do-notation. Sure, do-notation is implemented using monads under the hood, but you dont need to understand monads to use it, just as you dont need to understand vtables to use objects.
I should propably write a do-notation tutorial to show how far you can get without understanding monads.
I think that when teaching or learning monads the concept to focus on is composing smaller units (computations) into larger ones (aggregate computations), often by passing the output from one computation into the next one. It's also important to understand that once you have composed several small computations into a large computation you do not care or necessarily even know that the large computation is composed of smaller ones.
After meditating on that idea for a while it's necessary to see many different examples of useful monads. The 'All About Monads' tutorial (probably the best monad tutorial) has a section which is all examples. You need to see as many examples as possible because you can't understand monads by looking at a single specimen.
Monads are an abstract generality which provides a similar structure to many different things that you would never have expected to have much in common. Without understanding that commonality, you're missing the point and monads will remain incomprehensible.