Comment by dminik

Comment by dminik a day ago

9 replies

It's funny, but I do actually like it. It's just that it walks like a duck, swims like a duck and quacks like a duck.

I don't have a problem with IO conceptually (but I do have a problem with Zig ergonomics, allocator included). I do have a problem with claiming you defeated function coloring.

Like, look. You didn't even get rid of await ...

> try a_future.await(io);

n42 a day ago

I do want to say that I regretted that comment as nonconstructive after it was too late to edit it. Others in the thread are representing my argument better than I can or care to.

mlugg a day ago

I mean... you use `await` if you've used `async`. It's your choice whether or not you do; and if you don't want to, your callers and callees can still freely `async` and `await` if they want to. I don't understand the point you're trying to make here.

To be clear, where many languages require you to write `const x = await foo()` every time you want to call an async function, in Zig that's just `const x = foo()`. This is a key part of the colorless design; you can't be required to acknowledge that a function is async in order to use it. You'll only use `await` if you first use `async` to explicitly say "I want to run this asynchronously with other code here if possible". If you need the result immediately, that's just a function call. Either way, your caller can make its own choice to call you or other functions as `async`, or not to; as can your callees.

  • dminik a day ago

    > in Zig that's just ...

    Well, no. In zig that's `const x = foo(io)`.

    The moment you take or even know about an io, your function is automatically "generic" over the IO interface.

    Using stackless coroutines and green threads results in a completely different codegen.

    I just noticed this part of the article:

    > Stackless Coroutines > > This implementation 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. > > This execution model is compatible with WASM and other platforms where stack swapping is not available or desireable.

    I wonder what will happen if you try to await a future created with a green thread IO using a stackless coroutine IO.

    • mlugg a day ago

      > Well, no. In zig that's `const x = foo(io)`.

      If `foo` needs to do IO, sure. Or, more typically (as I mentioned in a different comment), it's something like `const x = something.foo()`, and `foo` can get its `Io` instance from `something` (in the Zig compiler this would be a `Compilation` or a `Zcu` or a `Sema` or something like that).

      > Using stackless coroutines and green threads results in a completely different codegen.

      Sure, but that's abstracted away from you. To be clear, stackless coroutines are the only case where the codegen of callers is affected, which is why they require a language feature. Even if your application uses two `Io` implementations for some reason, one of which is based on stackless coroutines, functions using the API are not duplicated.

      > I wonder what will happen if you try to await a future created with a green thread IO using a stackless coroutine IO.

      Mixing futures from any two different `Io` implementations will typically result in Illegal Behavior -- just like passing a pointer allocated with one `Allocator` into the `free` of a different `Allocator` does. This really isn't a problem. Even with allocators, it's pretty rare for people to mess this up, and with allocators you often do have multiple of them available in one place (e.g. a gpa and an arena). In contrast, it will be extraordinarily rare to have more than one `Io` lying around. Even if you do mess it up, the IB will probably just trip a safety check, so it shouldn't take you too long to realise what you've done.

      • dminik a day ago

        I find these two statements to be contradictory

        > Sure, but that's abstracted away from you

        > Mixing futures from any two different `Io` implementations will typically result in Illegal Behavior

        Thinking about it more, you've possibly added even more colors. Each executor adds a different color and while each function is color-agnostic (but not colorless) futures aren't.

        > it will be extraordinarily rare to have more than one `Io`

        Will it? I can immediately think of a use case where a program might want to block for files on disk, but defer fetching from network to some background async executor.

      • dminik a day ago

        Also, I do find it funny that we went from "Zig has completely defeated function coloring" to "Zig has colored objects".