Does async/await solve a real problem?

Mark S. Miller erights at
Thu Sep 11 07:55:44 PDT 2014

On Thu, Sep 11, 2014 at 7:22 AM, Florian Bösch <pyalot at> wrote:

> A -> B -> C -> D -> E changes to
> A -> B -> C -> D -> async E and causes
> A await -> B await -> C await -> D await -> async E
> And of course if A, B, C or D is used anywhere else it percolates trough
> the entire call graph.
> Trying to protect people from interlaved code execution effects is noble.

Exactly. Good to see we agree on the implications even if we value these
outcomes differently.

> But doing so by introducing a rote thing to type everytime you change the
> code somewhere underneath is wrong. It's wrong because it breaks logic
> isolation, it becomes impossible to change part of the library/utiity code
> without this change affecting all code that uses it. This guarantees that
> it doesn't happen in practice, because it's too painful to do. It requires
> the code, that uses other code, to know about the internal behavior of that
> code.
> If say, I'd propose a semantic that required you to write "foo" in the
> code, but just for those pieces of code that contain mentions of "bar", or
> that reference code that contains "bar" to the Nth degree, you'd accuse me
> of trying to introduce a purposefully unusable feature. How is await/async
> not an unusable feature?

On Thu, Sep 11, 2014 at 7:25 AM, Florian Bösch <pyalot at> wrote:

> Furthermore, since await is call graph infectious, for those really
> wanting to use it, it means that before long, await is written before every
> single function call. Which makes no sense.

In a purely functional system without side effects of any form (i.e.,
ignoring even strictness and exceptions), interleaving is harmless, so this
conclusion is valid. You would indeed safely get better code reuse if you
placed async/await everywhere, so that instead should have been the default
in such a language. In fact, since interleaving is harmless, you can
schedule all computation as you like, including in parallel, lazily,
eagerly, whatever, without harming correctness. In the absence of side
effects, we should indeed not have placed a notational burden on
interleaving points.

But in an imperative system with synchronous side effects that co-exists
with interleaving hazards, we also needs a way to protect against such
hazards. The economy of the communicating event loop model is that each
turn is implicitly a mutually exclusive atomic transaction -- without
needing extra notation for synchronization or transaction boundaries.

The cost of making atomicity cheap is that interleaving points must be made
explicit. With callbacks, this cost is quite high. Promises reduce this
cost substantially. async/await further reduces this cost about as far as
it can be reduced, while still leaving an explicit marker.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list