By the way, Rust's runtime also have a similar issue to Zig's `Io` (making the runtime available to the code, similarly to how you need to make an `Io` instance available in Zig). Rust runtimes just decided to use thread locals for that, and nothing stops you from doing the same in Zig if you want to.
I hope you can see that this is all orthogonal to the "colored functions" problem. When I was talking about tradeoffs however I was referring to the use of a threaded/green thread implementation under the hood as opposed to a stackless coroutine. The first two are less invasive at the language level and don't require function coloring (hence why Zig didn't solve, but also doesn't have, function coloring!) however they can be more limiting (they are not always available, especially on embedded and on wasm) and less extensible (most operations need to be explicitly supported in `Io`, as opposed to being implementable by anyone).
A great example is React Suspense. To suspend a component, the render function throws a Promise. To trigger a parent Error Boundary, the render function throws an error. To resume a component, the render function returns a result. React never made the suspense API public because it's a footgun.
If a JS Promise were inspectable, a synchronous render function could poll its result, and suspended components would not need to use throw to try and extend the language.
Well, technically you can run a nested event loop, I guess. But that's such a heavy sync-wrapping-async solution that it's rarely used other than as a temporary hack in legacy code.
This Io business is isomorphic to async/await in Rust or Python [1]. Go also has a built-in "event loop"-type thing, but decidedly does not have a coloring problem. I can't think of any languages besides JS that do.
context is kind of a function color in go, and it's also a function argument.
Looking back at the original function coloring post [1], it says:
> It is better. I will take async-await over bare callbacks or futures any day of the week. But we’re lying to ourselves if we think all of our troubles are gone. As soon as you start trying to write higher-order functions, or reuse code, you’re right back to realizing color is still there, bleeding all over your codebase.
So if this is isomorphic to async/await, it does not "solve" the coloring problem as originally stated, but I'm starting to think it's not much of a problem at all. Some functions just have different signatures from other functions. It was only a huge problem for JavaScript because the ecosystem at large decided to change the type signatures of some giant portion of all functions at once, migrating from callbacks to async.
[1]: https://journal.stuffwithstuff.com/2015/02/01/what-color-is-...
I don't see how that's not the exact same situation.