
Why monads have not taken the Common Lisp world by storm (2008) - platz
http://marijnhaverbeke.nl/monad.html
======
Chattered
"It appears that in the presence of mutable state, a lot of the advantages of
monads become moot."

If you have imperative state then toy uses of the state monad might be
overkill. But, for example, in a parser, imperative state is unlikely to help
you. Here, you want state to be discarded at failure and old states restored
by backtracking. The execution paths are highly complicated (as they always
are when you are working with what are effectively continuations), and trying
to reason about these paths in the face of imperative update isn't easy, and
is likely to lead to weird bugs.

Toy examples are not generally going to help you appreciate monads, and I
think there's a fourth requirement to make them work in a language: you need a
powerful type-system. I'd say that monads haven't taken F# by storm because F#
isn't powerful enough to type-check a library for arbitrary monads. And you
want that, because when it comes to reasoning about code using such libraries
and then applying it to a monad assembled from a stack of several other
monads, you really want your type-checker around.

Ocaml's type-system is powerful enough for this, and I still reach for my
monad library when writing Ocaml code. It's syntactically heavier than
Haskell, but not too painful. The solution is to make all your monads into
modules, which would be a bit like making every monad a dictionary and passing
it around explicitly. This is basically what Haskell ends up doing with type-
classes anyway, and what Gabriel Gonzalez has suggested one do explicitly:

[http://www.haskellforall.com/2012/05/scrap-your-type-
classes...](http://www.haskellforall.com/2012/05/scrap-your-type-classes.html)

If you follow this approach, Common Lisp and any other language can pull it
off by making all monads into dictionaries. All you lose is the type-checking.

~~~
zak_mc_kracken
> If you have imperative state then toy uses of the state monad might be
> overkill

What's imperative state? These are two very different concepts.

Both functional and imperative code can be manipulating state, and that state
can be either mutable or immutable.

Haskell is often considered to be both a functional and an imperative language
(see how linking do statements works).

I'm guessing you meant to say "mutable state" above?

~~~
nbouscal
I don't know who you've been talking to that considers Haskell to be an
imperative language, but that's nonsense. Haskell is about as far from multi-
paradigm as you can get. Do-notation is nothing but syntactic sugar for
regular monadic expressions, which are pure functional in every way.

~~~
zak_mc_kracken
Merely quoting Simon Peyton Jones and Philip Wadler in their paper from 1993
"Imperative Functional Programming" [1].

Chaining monadic binds with a `do` is the textbook example of imperative
programming (it's actually the very reason why the keyword 'do' was chosen for
syntactic sugar, because it captures perfectly the imperative aspect: "do this
and in this order").

You seem to think it's a bad word but I really don't understand that. Haskell
is both functional and imperative, there's really nothing wrong about it.

[1] [http://research.microsoft.com/en-
us/um/people/simonpj/Papers...](http://research.microsoft.com/en-
us/um/people/simonpj/Papers/imperative.ps.Z)

~~~
nbouscal
Huh. We clearly mean different things by "imperative programming". To me,
sequential computation is a necessary but really-far-from-sufficient aspect of
imperative programming. A monadic expression is still an expression, not a
statement. It is still referentially transparent. I don't know how you can
look at a referentially transparent expression and call it imperative other
than by being very liberal with your definitions.

------
marijn
Author here. I am considering putting a "this is ancient, please don't submit
it to social linking sites" header on top this. It's appeared on here two
times in the past year. It never was a very good article to begin with, and
six years later, it just looks lame.

~~~
gus_massa
Don’t worry, no article is perfect. I found this article interesting and maybe
I’ll try some of these ideas in Racket.

Previous discussions (they have different submitters and a slightly different
URL):

[https://news.ycombinator.com/item?id=6398393](https://news.ycombinator.com/item?id=6398393)
(63 points, 221 days ago, 48 comments)

[https://news.ycombinator.com/item?id=448293](https://news.ycombinator.com/item?id=448293)
(33 points, 1918 days ago, 27 comments)

------
olenhad
For clojure, there's kern
([https://github.com/blancas/kern](https://github.com/blancas/kern)) for
parsec style parser combinators. It's quite easy to use. Ironically, I
actually understood parser combinators better by reading its wiki (By
understood, I mean understood how to _use_ parser combinators). Parsec was
initially difficult to grasp because the type system complicated things for me
then. I only got Parsec completely after that eureka moment when I finally
understood Monads.

~~~
angerman
While not directly monad related. There's also instaparse
([https://github.com/engelberg/instaparse](https://github.com/engelberg/instaparse))
which has also pretty nice presentation.
[https://www.youtube.com/watch?v=b2AUW6psVcE](https://www.youtube.com/watch?v=b2AUW6psVcE)

I just wanted to leave this here as if it hadn't been for twitter and the
presentation, I would likely never have known about it.

~~~
mrottenkolber
Also, nobody cares. Since this comment is not even remotely related anymore.

------
dschiptsov
Because they make no sense for a dynamic [but strong] typing language?)

[http://karma-engineering.com/lab/wiki/Monads](http://karma-
engineering.com/lab/wiki/Monads)

~~~
platz
Douglas Crockford seems to think otherwise:
[http://www.youtube.com/watch?v=b0EF0VTs9Dc](http://www.youtube.com/watch?v=b0EF0VTs9Dc)

~~~
copergi
He also gets a lot wrong in that talk, so that doesn't seem like a
particularly compelling case.

~~~
alanning
Could you point out some of the issues you noticed in the talk? (Asking from
the point of view of someone curious about monads.)

~~~
habitue
From watching half of it, he mistakes monads for being a trick to avoid Io,
which is not true. Io really does happen in Haskell, it is just contained.
Also he mentions types not being necessary to understand monads, but
immediately launches into a description of the bind and unit functions by, you
guessed it, stating what the types of the function's were and what kinds of
things they returned (I.e. the exact thing he said he wouldn't talk about on
the previous slide).

That being said, I liked his reworking of bind to be a method on an object. I
agree monadic computation is tedious to read when you don't have an infix bind
operator, and his trick of turning bind into a method solves that pretty well
in a language like JavaScript.

I think he's probably overstating the case that what he calls ajax chaining is
always monadic (but what most of us who didn't write a competing library would
call jquery style method chaining). I would guess most implementations of this
kind of APIs do not adhere to the monad laws.

------
nnq
Let me guess, the 'parser for a reasonably complicated language' was actually
a Javascript parser written in CL, more exactly what is today
[http://marijnhaverbeke.nl/parse-js/](http://marijnhaverbeke.nl/parse-js/) ?

------
mrottenkolber
See [http://mr.gy/maintenance/mpc](http://mr.gy/maintenance/mpc) (self-plug).

A friendly fork of Drew Crampsie's Smug¹.

MPC is a monadic parser combinators library. It provides a toolbox of
predefined parsers, facilities for error handling and parses arrays, streams
and lists.

[1] [https://github.com/drewc/smug](https://github.com/drewc/smug)

------
nathell
There's cl-parser-combinators ([https://github.com/Ramarren/cl-parser-
combinators](https://github.com/Ramarren/cl-parser-combinators)), which is
supposed to aid in writing parsers in a painless, Parsec-like way. I haven't
used it, but it may be worth a try.

------
kbd
Needs a (2008)

