Need help?
<- Back

Comments (37)

  • spankalee
    Wow, this is really helpful and timely!I'm building a new language with async/await and had to make a lot of these decisions, but I didn't have this organized of a framework to ground myself in. I'm happy to see it clearly that I choose mostly Trio with a bit of JavaScript.My language (Zena's) async docs page: https://zena-lang.dev/guide/async/ I think I might do a pass and try to call out the decision points more explicitly.fwiw, I found this post on cancellation by the author of Trio to be vey compelling: https://vorpus.org/blog/timeouts-and-cancellation-for-humans... and I based the cancellation design of Zena on it.Edit to add: I do wish this included JavaScript's AbortSignal in the Cancellation section. Not because it's good, but because passing cancel tokens is a pattern that exists. There's also the dimension of who can cancel and, like AbortSignal, whether tasks have to opt-in to cancellation checks.
  • biorach
    It's long been clear that there were fundamental implementation choices that mattered between async runtimes, but _nine_ design dimensions? Damn.I think async is deceptive in that it seems like a self-contained and relatively straightforward aspect of a language. But there are many design choices to be made and they all have wide implications.Plus I think the implications of many of these dimensions are not fully understood and that collectively we are still trying to understand how they are playing out in implementations. Add to this the subtle nature of some of the implications plus the combinations...I think a good comparison is lexical vs dynamic scope in programming languages. This is a design dimension that was argued over for a decade or two in the early years of programming language design. It was only as time went by, and experience gained by working with concrete implementations that it became clear that lexical scoping should be the default choice and dynamic scoping should be restricted to various niches.
  • jcelerier
    I was wondering "hopefully C++ allows you to pick across these axes so that you can build yourself the async primitives that work best for the problem at hand" and then: yes!> We cannot attribute C++ to any particular design point in the taxonomy provided in Table 1 because each axis is configurable. Although elegant and neutral, the choice of full programmability makes each library an async dsl; knowledge transfer between projects within the same language becomes exceedingly difficult.It is not if you think in terms of these axes and which solve your particular problem and not any particular specific design. Take for instance the simplest program one can imagine: a network video player. E.g. some server sends you RTP audio & video frames and you have to play them back correctly, with a nice GUI on top. If you want to do this in a way that is as efficient as possible you need to be aware of all possible ways of async interoperation:- connecting & receiving packets from the network in a classic network state machine where coroutines shine- handling vsync vs not-vsync for displaying the video frame- conforming to whatever async paradigm the hardware video decoding system you want to use is going to provide you with, e.g. Intel QuickSync vs VideoToolbox vs NVDEC...- handling the synchronous model of audio playback driven in pull mode- handling the synchronisation between audio / video, and thus the async patterns that support multi-threading as your audio thread can't be your video or GUI thread- handling the async model of your GUI library for your play / stop button's callbacks.There's zero chance that a single async model fits all of these equally well without tradeoffs, so you have to have the knowledge anyways.
  • hankbond
    > You must be a JavaScript developer.and i took that personally
  • biorach
    At last someone took the time to pore over all the tedious crap that I have been trying and failing to keep straight in my head since forever.
  • homarp
    The paper explores how async/await behaves across today's languages: https://arxiv.org/abs/2608.20677
  • rao-v
    I remember being so mad years ago, coming from a pure CS background, when it dawned on me that async await was “mere” control flow and not actual parallelism.It’s why I feel go (with go routines being the norm) is one of the few imperative languages that was designed vs. filling out a bunch of historical constraints (apologies this is not meant to trigger a language debate, just an idiosyncratic thought)
  • alilleybrinker
    With these dimensions of design variance defined, you could also make a closeness measure in 9-dimensional space and identify the most or least similar combos.Also a great teaching tool, if someone knows one async system, to be able to show them the differences on each axis from their prior one to a new one they’re learning.
  • bradleybuda
    I answered the quiz and it said "you must be a Javascript developer", which is true enough - that's probably my second-most-proficient language. In fact, I'm a Ruby developer partially because I hate the idea of async/await and I'm feeling very smug about my choice after reading this.Some of these design decisions seem indefensible to me. For example, what the authors call "Suspension":-> Static: Await points guaranteed to suspend -- JavaScript-> Dynamic: No guarantees on awaiting tasks -- C# · Swift · Tokio · Smol · Asyncio · TrioWhat is "await" if not a synonym for "suspend"?!?async/await is one product of a long line of thought that says "threads are too hard for programmers to get right". Threads (really, shared memory) have real usability issues for developers, but once you grok the semantics (which largely map to the physical execution model in a CPU) that knowledge is transferrable across virtually all languages and runtimes.
  • glaslong
    C# is my primary, but the quiz tells me I'm a JS dev.Feel like I should assign myself a couple dozen Jon Skeet posts to read now, to make up for this embarrassment.
  • perrygeo
    Amazing work. It's one thing to say "async is complex". It's another to parse that statement so carefully as to have a cross-language theory of async execution. Looking forward to digging into this!
  • layer8
    It would be a fun coding agent benchmark to have them translate such a program between the different languages and see whether they preserve the respective semantics.
  • vitaminCPP
    Love it. I wish it included zig.
  • moralestapia
    Great work. Must read for anyone working with this type of concurrency.
  • slopinthebag
    Maybe it’s cuz I started with async/await instead of threads but I cannot relate to people saying it’s harder than threading. To me it’s substantially easier to understand than threads, goroutines, or structured concurrency in Kotlin.
  • cbm-vic-20
    or, Java Virtual Threads and chill.
  • jdw64
    >You must be a C#, Swift, Asyncio, or Tokio developer — hard to narrow down, you all agree on this one.I think that's definitely right. Knowing the semantics of the language you mainly use is important.
  • agumonkey
    Beautiful
  • holt62
    Nine dimensions proves it: async isn't a feature, it's a set of tradeoffs. C++ configurable on all of them is why every codebase reinvents its own semantics.