4 ms·
I'd like to point out that do-notation in Haskell is a syntax sugar for something nasty. Let's look at the example: do a <- getData b <- getMo
by m1el 9y ago
I'd like to point out that do-notation in Haskell is a syntax sugar for something nasty.
Let's look at the example:
do
a <- getData
b <- getMoreData a
c <- getMoreData b
d <- getEvenMoreData a c
print d
This desugars to:
bind getData (
bind (\a -> getMoreData a) (
bind (\b -> getMoreData b) (
bind (\c -> getEvenMoreData a c)
\d -> print d)))
Edit: the above code was initially wrongly desugared.
Which is exactly the callback hell criticized in the article.
Sure, monads and do-syntax provide a nice abstraction and are interesting constructs from the perspective of type theory, but in my opinion it's not principally better than Promises or await.
- zoul 9y agoIMHO callback hell is only called hell because of the syntax. So the solution admired here is mostly the do notation, not monads themselves. (But it’s a great feature that the do notation can be used for a general class of problems represented by monads, not a particular one as await, for example.)
- m1el 9y agoIf do-notation is the solution, does that mean that adding syntax sugar for nested functions / promises in JS would solve the problem of callback hell as well? I somehow doubt that.
- klmr 9y agoYes — but only if, as in Haskell, that syntactic sugar was generalisable. The whole point of monads is that they are a powerful generalisation that can be used to solve many apparently very different problems. Compared with the syntactic sugar that other languages introduce to solve specific problems (list comprehension/LINQ, `await`, …). You suddenly get a grammar explosion because you keep expressing the same core concept differently.
- scotty79 9y ago> Yes — but only if, as in Haskell, that syntactic sugar was generalisable. Only if you just need one type of monad. If you need interleave multiple monads, haskell syntax is worse because it makes no visible distinction between them.
- tathougies 9y agoThere is no sensible interleaving of multiple monads, and any sensible language would prevent you from any kind of implicit interleaving.
- scotty79 9y agoIn the article there are few monads mentioned: async, nested iteration, maybe, state passing. I can easily imagine sensible mixture of those, and languages with "ad hoc" solutions allow you to mix them.
- tome 9y agoThe distinction is visible in the type.
- mej10 9y ago... you mean like async / await?
- tathougies 9y agoIf async await worked for the continuation monad, the typical list monad, and the maybe monad, then yes, async/await would be a good, if somewhat strangely named, construct
- unhammer 9y ago`bind` is usually written as `>>=` in Haskell. Haskell also lets you write simply print instead of \d -> print d I wouldn't consider this part syntactic sugar – if one did, I suppose one would have to say that f(g()) in Python is sugar for (lambda i: f(i))((lambda: g())()) Here's how the desugared version looks in more idiomatic Haskell: getData >>= \a -> getMoreData a >>= getMoreData >>= getEvenMoreData a >>= print (where I kept the lambda around the first getMoreData since `a` was used in getEvenMoreData)
- deleted 9y ago[deleted]
- js8 9y ago> I'd like to point out that do-notation in Haskell is a syntax sugar for something nasty. [..] Which is exactly the callback hell criticized in the article. What's even worse - the resulting code gets compiled to machine code. That's usually very ugly, there is a limited number of variables (registers), and you have to juggle them around. So, obviously, it's no better than writing the machine code by hand. See, that's the purpose of compilers - to take readable abstractions and to turn them into unreadable, but efficient, mess that is actually executed.
- saurik 9y agoThe whole point is that do syntax is a generic solution to an entire class of problems, while async/await is a one off solution to a single problem.