I [author] must say I'm slightly embarrassed to see this turn up here now. This is not a terribly deep or interesting post. Read <a href="http://marijnhaverbeke.nl/blog/tern.html" rel="nofollow">http://marijnhaverbeke.nl/blog/tern.html</a> or <a href="http://marijnhaverbeke.nl/blog/acorn.html" rel="nofollow">http://marijnhaverbeke.nl/blog/acorn.html</a> or <a href="http://marijnhaverbeke.nl/blog/browser-input-reading.html" rel="nofollow">http://marijnhaverbeke.nl/blog/browser-input-reading.html</a> instead.
> It appears that in the presence of mutable state, a lot of the advantages of monads become moot.<p>In the simpler cases where use of monads can be replaced by simple mutable state -- you still lose out on the explicit types of the mutating vs. pure code.<p>For example, STM is possible because mutating effects are typed, and so can be ruled out of STM transactions.<p>And in the more complex monads (e.g: transformer stacks), mutable state is just not good enough. You can compose transformers to build things that mutable state simply cannot express, and you'd have to CPS transform your code and avoid mutable state to express those things.<p>For example, these two monads:<p><pre><code> ListT (ParsecT m)
ParsecT (ListT m)
</code></pre>
Have no corresponding "mutable state" representations.
Incidentally, I am just reading through All About Monads (<a href="http://www.haskell.org/haskellwiki/All_About_Monads" rel="nofollow">http://www.haskell.org/haskellwiki/All_About_Monads</a>) and his point 3 ("Allow polymorphism on return types") is what confused me in this example:<p><pre><code> getAny :: (Random a) => State StdGen a
getAny = do g <- get
(x,g') <- return $ random g
put g'
return x
</code></pre>
I was like.. how on Earth Haskell knows which function "get" should it call? I think this is a point which should be more stressed in the tutorials (I read Learn yourself a Haskell and glanced at couple of others..)
<p><pre><code> * Try to quickly write the whole thing as a single recursive descent parser. Note the exploding amount of ugliness. Give up.
* Separate out the tokenizer (novel idea, huh?) to keep parser complexity down. Parser is still a mess. Ugh!
* Play around with some CL parser frameworks. This helps a bit, but none of the systems I tried produce errors with enough information.
* Remember the breeze it was to write a parser with the Haskell Parsec library. Mess around with monads for a while, learn a few things, but not how to write elegant parsers in Common Lisp.
</code></pre>
I've been going through these exact steps but in JavaScript. Writing languages is fun! And makes me want to kill things!
I came here to make a joke about the real reason why was that no one understands them... but apparently everyone here does. Off to google monads for idiots...
Nah, I think its just because they result in really nested types which is hard to keep track of without a really good type system. Using a single monad by itself like error or continuation is straightforward in Clojure; there are smart & vocal people who do this. But the super awesome OMFG of monads is that they can be combined (e.g. parser = error + state), and this more or less requires abstracting in the type system to keep track of all the lambdas.
>That's a little too blatantly useless to be interesting though. But note how ugly CL's multiple namespaces make liftmaybe and its uses.<p>Oh yeah, incredibly ugly \s<p>OP, you may be interested in checking out LiL, the Lisp interface Library.<p><a href="https://github.com/fare/lisp-interface-library" rel="nofollow">https://github.com/fare/lisp-interface-library</a>
There is a point made here about how Haskell's namespace handling makes monads easy, while CL's makes them ugly. I don't know enough about CL's namespaces to understand this. Can someone explain?