Live data from Hacker News

Why monads have not taken the Common Lisp world by storm (2008)

marijnhaverbeke.nl

11–20 of 49 posts

Re: Why monads have not taken the Common Lisp world by storm (2008)

#11
post #5
post #2

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 http://marijnhaverbeke.nl/blog/tern.html or http://marijnhaverbeke.nl/blog/acorn.html or http://marijnhaverbeke.nl/blog/browser-input-reading.html instead.

Don't be. The fundamental observation that monad's usability is tied closely to Haskell's features is important, and still hasn't been taken on board elsewhere. There's always someone trying to do monads in Clojure...

Yup. If I had read this article when it was first written instead of now, I probably would have produced a fair bit less unnecessarily complicated and difficult-to-maintain code over the past several years.

Instead, I had to figure out why I was having such a hard time coming up with a satisfactory implementation of the pattern in C# - and why I maybe shouldn't have wanted one in the first place - the hard way.

Re: Why monads have not taken the Common Lisp world by storm (2008)

#12
post #2

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 http://marijnhaverbeke.nl/blog/tern.html or http://marijnhaverbeke.nl/blog/acorn.html or http://marijnhaverbeke.nl/blog/browser-input-reading.html instead.

Don't be embarrassed about this. I think it's a very important point. I've heard monads getting buzz outside the Haskell community and it almost always misses the point. I gave a presentation at the NYC Haskell meetup that made essentially the same point as you, but came at it from a different angle. You wrote this post quite awhile earlier, but it's nice to know that we independently came to the same conclusions.

Re: Why monads have not taken the Common Lisp world by storm (2008)

#13

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...

This talk by Douglas Crockford is quite informative:

http://www.youtube.com/watch?v=dkZFtimgAcM

Re: Why monads have not taken the Common Lisp world by storm (2008)

#14

  * 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.
I've been going through these exact steps but in JavaScript. Writing languages is fun! And makes me want to kill things!

Re: Why monads have not taken the Common Lisp world by storm (2008)

#15
post #4

> It appears that in the presence of mutable state, a lot of the advantages of monads become moot. 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. For example, STM is possible because mutating effects are typed, and so can be ruled out of STM transactions. And in the more complex monads (e.g: transformer stacks…

That's a really great point that I rarely see come up. Yes, Haskell makes you "recreate" the RWST monad stack that imitates impure languages... but the same tools also let you build other "language domains" which are fiendishly difficult to implement in non-pure settings (on par with CPS transforming yourself into the mother monad and then working backwards from there).

On Lisp has a chapter devoted to making a leaky macro-based CPS transformer for Common List. ContT adds CPS to any monad stack as quickly as

    newtype ContT r m a = ContT { runContT :: (a -> m r) -> m r }

Re: Why monads have not taken the Common Lisp world by storm (2008)

#16

Incidentally, I am just reading through All About Monads ( http://www.haskell.org/haskellwiki/All_About_Monads ) and his point 3 ("Allow polymorphism on return types") is what confused me in this example: getAny :: (Random a) => State StdGen a getAny = do g 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…

It's easy for a Haskell expert to sweep typeclass resolution under the rug, but it's definitely some pretty black magic at first no matter how "simple" its implementation is. The reality is that the compiler works really hard to ensure that it can guess the right "get" and it's pretty possible for it to fail.

Of course, when it fails you know immediately and can remedy it by type annotations, but that can still be challenging.

To answer the question, `get` has its principle type resolved by the type inference engine. In this case, `get`'s most general type is `MonadState s m => m s` and it can resolve what `m` is by unifying it with the type annotation of `getAny`, so we know that we need `get :: MonadState s (State StdGen) => State StdGen s`. From here, the compiler searches through the type class instances in a Prolog-like style to find that `MonadState s (State StdGen)` occurs when `s ~ StdGen`. This resolves more type information and also tells us which definition of `get` is needed—the one that was defined as `instance MonadState s (State s) where`!

The end result is that get ends up with the type `get :: State StdGen StdGen` and is the function defined as `get = State $ \s -> (s, s)`.

Re: Why monads have not taken the Common Lisp world by storm (2008)

#17

* 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 wit…

I have no idea what you're working on, but I spent a few weeks this summer writing parsers and trying to figure out how to tackle the ugliness that seems to be inherent in hand-written recursive descent parsers. While I learned a lot, I am not an expert by a long shot. However I did find an interesting technique that is not well covered elsewhere.

I came across this* article, which uses JavaScript as the implementation language, and found it very interesting, in large part because this approach (Top down operator precedence) sort of pulls the precedence hierarchy out of the call graph of a recursive descent parser and into a table, but also because it's an approach that OOP (and JavaScript in particular) is well suited to. I've used it (in combination with traditional recursive descent) in a functional setting (Standard ML) as well, and would use it again, especially for parsing infix expressions (arithmetic expressions, type annotation expressions).

This is a bit of a tangent, but I thought you might be interested given the intersection of parsing and JavaScript. I've been meaning to write this up in a short blog post...

* http://javascript.crockford.com/tdop/tdop.html There's another article on this using Java as the implementation language: http://journal.stuffwithstuff.com/2011/03/19/pratt-parsers-e...

Re: Why monads have not taken the Common Lisp world by storm (2008)

#18

* 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 wit…

Tried this? http://tinlizzie.org/ometa/

Re: Why monads have not taken the Common Lisp world by storm (2008)

#19

* 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 wit…

I have no idea what you're working on, but I spent a few weeks this summer writing parsers and trying to figure out how to tackle the ugliness that seems to be inherent in hand-written recursive descent parsers. While I learned a lot, I am not an expert by a long shot. However I did find an interesting technique that is not well covered elsewhere. I came across this* article, which uses JavaScript as the implementati…

I like the precedence climbing algorithm since you can easily fit it into a normal recursive descent parser and it allows you to easily add new operators just by putting them in a table. See: http://eli.thegreenplace.net/2012/08/02/parsing-expressions-...

Re: Why monads have not taken the Common Lisp world by storm (2008)

#20
post #13

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...

This talk by Douglas Crockford is quite informative: http://www.youtube.com/watch?v=dkZFtimgAcM

Cool thanks!
Post reply on HN