You can write to one file, wait, and then write to the second file.
Concurrency not required.
Example 2
You can NOT do Server.accept, wait, and then do Client.connect, because Server.accept would block forever.
Concurrency required.
> Unfortunately this code doesn’t express this requirement [of concurrency], which is why I called it a programming error
I gather that this is a quirk of the way async works in zig, because it would be correct in all the async runtimes I'm familiar with (e.g. python, js, golang).
My existing mental model is that "async" is just a syntactic tool to express concurrent programs. I think I'll have to learn more about how async works in zig.
This is an artifact of wanting to write async code in environments where "threads" and "malloc" aren't meaningful concepts.
Rust does have a notion of autonomous existence: tasks.
Many other languages could already use async/await in a single threaded context with an extremely dumb scheduler that never switches but no one wants that.
I'm trying to understand but I need it spelled out why this is interesting.
And with green threads, you can have a call chain from async to sync to async, and still allow the inner async function to yield through to the outer async function. This keeps the benefit of async system calls, even if the wrapping library only uses synchronous functions.