Comment by kristoff_it

Comment by kristoff_it a day ago

8 replies

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.

dminik a day ago

Well, 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 a day ago

    I 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 16 hours ago

      In ruby async is based on stackful fibers. With 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.

  • thayne 10 hours ago

    > And it basically blocks you from doing FFI

    It doesn't block it. But it does make FFI much more expensive in go than in languages like Rust, because every foreign call needs to set up a c-compatible stack.

ismailmaj a day ago

The 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

  • laserbeam a day ago

    There 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.

  • throwawaymaths a day ago

    you could still have a library-global io, let the user set it as desired.

    > use of two different implementations of io

    functionally rare situation.