Zig Colourless Async in Rust

I haven't written/seen enough Zig to have a developed opinion. If what you've said is accurate, though, Zig runs the sync function synchronously at the point of async call() (runs to first await point), so await it is a no-op. In my hypothetical model, both synchronous and asynchronous code would be equally deferred when you create the thunk, and only evaluated once you evaluate them (notably, using e.g. join([f1, f2]) to evaluate multiple thunks concurrently).

My hypothetical runtime would also transparently push work into worker threads if a blocking call had to be made. Ideally, it would even shift coroutine threads into the spawn_blocking thread pool if they don't yield quickly enough, with all the management complexity that brings. The caller should not be able to tell the difference between a function implemented via blocking OS calls or expensive computation; they should be functionally identical to cooperative multitasking (which should be the default).

I did say this is a scripting language fantasy, not a systems language fantasy :slightly_smiling_face:

Because it is. Just one where you've artificially limited it to a single choice at compilation time (which I should also note prevents any dynamic linking between libs that made incompatible choices (which I guess is no worse than the Rust status quo of all of the compiler flags have to be exactly equal?)).

This is unavoidable, though; there is no consumer OS which provides an async option for every synchronous call. Even if there were, you still need to support OSes where they don't, or even perhaps just the last version of the OS that was before everything could be async but's still in support. (A major feature draw of Rust making it suitable for performance sensitive work is that it doesn't really have a runtime (anymore than C does, anyway). That's actually a major selling point of our async design: that you can bring your own executor. Perhaps your executor is specially tuned to your hardware and beats the standard ones; we shouldn't preclude you using it.) Plus, this doesn't address locks at all; especially that some locks might want to be released during suspension, and some locks might need to be held over suspension points.

This is the main thread, and there's this other thread as well. Unfortunately, though, much of the discussion is scattered around the entire async.await bikeshedding, so there's a lot lost inside all of that.

It's also potentially worth checking out Kotlin's suspend fun/[semi]coroutines documentation.

2 Likes