Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> If anything, async-await feels like an extremely non-functional thing to begin with

Futures/promises (they mean different things in different languages), like many other things, form monads. In fact async-await is a specialization of various monad syntactic sugars that try to eliminate long callback chains that commonly affect many different sorts of monads.

Hence things like Haskell's do-notation are direct precursors to async-await (some libraries such as Scala's monadless https://github.com/monadless/monadless make it even more explicit, there lift and unlift are exactly generalized versions of async and await).

To see how async-await might be generalized, one could turn to various other specializations of the same syntax, e.g. an async that denotes a random variable and an await that draws once from the random variable.

To see the correspondence with a flatMap method (which is the main component of a monad), it's enough to look at the equivalent callback-heavy code and see that it looks something like

  Future(5)
    .flatMap(x ->
      doSomethingFutureyWithX(x)
        .flatMap(lookItsAnotherCallback)
    )


I'm not clear on if this is supposed to be disagreement or elaboration or education.

The fact that in a language like Haskell, you can perform something like async-await with futures (which are absolutely a kind of monad) in a natural way is precisely what I had in mind with what you quoted.

Regardless, the specific heritage of async-await syntax seems rooted in procedural languages (that do borrow much else as well from functional languages, yet are still not functional in any meaningful sense) like C# and python. They are absolutely an attempt to bring some of the power of something like monadic application (including do notation) into a procedural environment as an alternative to threads (green or otherwise), which hide the execution state machine completely.


> the specific heritage of async-await syntax seems rooted in procedural languages

I don't think so. Async-await in both syntax and semantics is pretty firmly rooted in the FP tradition.

For semantics, the original implementation in C#, and as far as I know most of its successors, is to take imperative-looking code and transform it into CPS-ed code. That's a classic FP transformation (indeed it's one of the paradigmatic examples of first-class functions/higher-order functions) and one of the most popular methods of desugaring imperative-looking code in a functional context.

For syntax, the idea of hiding all that CPS behind an imperative-looking syntax sugar is the whole reason why do-notation and its descendants exist. (Indeed, there's an even deeper connection there specifically around CPS and monads: https://www.schoolofhaskell.com/school/to-infinity-and-beyon...)

But my point was simply that there's a pretty straight line from CPS, monads, and do-notation to async-await and so I think it's pretty fair to say that async-await is rooted in the FP tradition.


You don't need async/await to do monadic comprehension in Scala, it's built into the language from the very beginning with `for`.

This was inspired by do notation, which came about ~1998.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: