Hacker News new | ask | show | jobs
by Garlef 2226 days ago
I think this is just a matter of perspective and actually having different colors is a good thing:

Thinking in terms of functional programming / category theory, this coloring seems to boil down to working with different arrows. The coloring in this case would correspont to signifying the target category of the arrows `arr/lift` function (For example async functions in JS should be morphisms in smth like the Kleisli category of the `Promise` functor).

The issue now seems to be that there are no nice native language constructs in most languages to work with arrows. What's missing are arrow comprehensions - the bridge between the compositional notation used in functional languages and the more traditional way of writing things like `const x = ...`. The vanilla functions without `async/await` are arrow comprehensions for the identity monad.

The reason why the `async/await` syntax works so well as compared to using `.then` is that it is basically arrow comprehension for the promise monad.

3 comments

"I think this is just a matter of perspective and actually having different colors is a good thing:"

I don't think it's a "good thing". I think it's a "cost". Even in nice functional languages, it's a cost, in that even with the nicest syntax there is you still get color cascades when you realizes deep in the middle of some deep function that you're in the wrong color.

There's a great case to be made that said nice functional languages, through a combination of ameliorating the costs and successfully obtaining benefits from the separation, mean that it's a good tradeoff.

Conventional imperative languages do not successfully obtain enough benefits from the specific color of "asynchronousness" (functional languages have many more colors than just that) to make it worth while. Covering it over with syntax wouldn't be enough, because it's not just a syntax problem. What you really need is to not have this particular color in the first place. (While arguably lacking other colors that you really need, but that's a story for a different day.)

Unless you refuse to pay even a little bit to avoid that color problem (which is a valid choice in some circumstances but I would submit a bad default choice for most code and most coders), we can increasingly see that there are languages that do not have the async color issue at all, and pay only modest performance prices to do so. As languages like Go and the Beam VM continue to progress, and are joined by other up-and-coming languages, even the problems with being unable to interact with C libraries fade as you can find something that does what you need for the most part. (And besides... personally I "blame" C rather than the languages trying to do better than C and then having trouble interacting with such primitive code.)

If you really need to run your computations in a separate context/arrow, making them explicit in the types is nice. Having general syntactic rules to build, compose and run them: great.

However, if you can avoid the additional arrow entirely: even better!

I mean Haskell of all languages has green threads and doesn’t need the entire promise shenanigans.

Even in Haskell I sometimes I build very specific DSLs for my domain to be interpreted in a separate step so I can freely fix my pure and impure code.

I have some vague knowledge of category theory, but not enough to follow your argument here. Especially the concept of an 'Arrow' could you explain more clearly what an arrow, and an arrow comprehension is?