3 ms·
Here's a trick to make every function red (or blue? I'm colorblind, you decide): var io: std.Io = undefined; pub fn main() !void { var impl = .
by kristoff_it 1y ago
Here's a trick to make every function red (or blue? I'm colorblind, you decide):
var io: std.Io = undefined;
pub fn main() !void {
var impl = ...;
io = impl.io();
}
Just put io in a global variable and you won't have to worry about coloring in your application. Are your functions blue, red or green now?
Jokes aside, I agree that there's obviously a non-zero amount of friction to using the `Io` intreface, but it's something qualitatively very different from what causes actual real-world friction around the use of async await.
> but the general problem behind function coloring is that of context
I would disagree, to me the problem seems, from a practical perspective that:
1. Code can't be reused because the async keyword statically colors a function as red (e.g. python's blocking redis client and asyncio-redis). In Zig any function that wants to do Io, be it blue (non-async) or red (async) still has to take in that parameter so from that perspective the Io argument is irrelevant.
2. Using async and await opts you automatically into stackless coroutines with no way of preventing that. With this new I/O system even if you decide to use a library that interally uses async, you can still do blocking I/O, if you want.
To me these seems the real problems of function coloring.
- ismailmaj 1y agoThe global io trick would totally be valid if you’re writing an application (i.e. not a library) and don’t have use of two different implementations of io
- throwawaymaths 1y agoyou could still have a library-global io, let the user set it as desired. > use of two different implementations of io functionally rare situation.
- laserbeam 1y agoThere are plenty of libraries out there which require users to do an init() call of some sorts at startup. It is perfectly possible to design a library that only works with 1 io instance and gets it at init(). Whether people like or want that… I have no clue.
- dminik 1y agoWell, it's not really a joke. That's a valid strategy that languages use. In Go, every function is "async". And it basically blocks you from doing FFI (or at least it used to?). I wonder if Zig will run into similar issues here. > 1. Code can't be reused because the async keyword statically colors a function This is fair. And it's also a real pain point with Rust. However, it's funny that the "What color is your function?" article doesn't even really mention this. > 2. Using async and await opts you automatically into stackless coroutines with no way of preventing that This however I don't think is true. Async/await is mostly syntax sugar. In Rust and C# it uses stackless coroutines. In JS it uses callbacks. There's nothing preventing you from making await suspend a green thread.
- kristoff_it 1y agoI should have specified that better, of course async and await can be lowered to different things (that's what Zig does afterall), what I wanted to say is that that's how it works in general. JS is a good counter example, but for all other mainstream languages, async means stackless coroutines (python, ruby, c#, rust, ...). Which means that if I want to use a dependency that uses async await, it's stackless coroutines for me too whether I like it or not.
- sczi 1y agoIn ruby async is based on stackful fibers. With https://github.com/socketry/async-debug https://github.com/socketry/async-debug you can see a tree of all fibers with their full call stack. It also avoids the problem people talk about in this thread with go of passing a context parameter everywhere for cancellation as you can kill or raise any exception inside another fiber. I haven't used them but PHP fibers are also supposedly stackful. And Java and every JVM language has them since project loom in JDK 21.
- kristoff_it 1y agoMy mistake, I should have said Python then.
- 1y ago