I see that blocking I/O is an option:
> The most basic implementation of `Io` is one that maps to blocking I/O operations.
So far, so good, but blocking I/O is not async.
There is a thread pool that uses blocking I/O. Still good so far, but blocking I/O is still not async.
Then there's green threads:
> This implementation uses `io_uring` on Linux and similar APIs on other OSs for performing I/O combined with a thread pool. The key difference is that in this implementation OS threads will juggle multiple async tasks in the form of green threads.
Okay, they went the Go route on this one. Still (sort of) not async, but there is an important limitation:
> This implementation requires having the ability to perform stack swapping on the target platform, meaning that it will not support WASM, for example.
But still no function colors, right?
Unfortunately not:
> This implementation [stackless coroutines] won’t be available immediately like the previous ones because it depends on reintroducing a special function calling convention and rewriting function bodies into state machines that don’t require an explicit stack to run.
(Emphasis added.)
And the function colors appear again.
Now, to be fair, since there are multiple implementation options, you can avoid function colors, especially since `Io` is a value. But those options are either:
* Use blocking I/O.
* Use threads with blocking I/O.
* Use green threads, which Rust removed [2] for good reasons [3]. It only works in Go because of the garbage collector.
In short, the real options are:
* Block (not async).
* Use green threads (with their problems).
* Function colors.
It doesn't appear that the function colors problem has been defeated. Also, it appears to me that the Zig team decided to have every concurrency technique in the hope that it would appear innovative.
[1]: https://gavinhoward.com/2022/04/i-believe-zig-has-function-c...
[2]: https://github.com/aturon/rfcs/blob/remove-runtime/active/00...
[3]: https://www.open-std.org/JTC1/SC22/WG21/docs/papers/2018/p13...