Live data from Hacker News

Zig's New Async I/O

kristoff.it

31–40 of 293 posts

Re: Zig's New Async I/O

#31

Earlier quoted context omitted.

It's hardly "all-in" if it is merely one choice of many, and the choice is made in the executable not in the library code.

I have definitely gotten the impression that green threads will be the favored implementation, from listening to core team members and hanging around the discord. Stackless coroutines don't even exist in the language currently.

What does "favored" mean if event loop and direct blocking are relatively trivial and provided also/ If I can trivially use them, what do I care what Andrew or someone in core thinks? The control is all mine, and near zero cost (potential vtable indirection).

And would Rust be "all-in" if tokio was in std, so you could use its tasks everywhere? That would be a very similar level of "all-in" to Zig's current plan, but with a seemingly better API.

I understand the benefit of not being in std, but really not a fundamental issue, IMO.

Re: Zig's New Async I/O

#32
post #29

Earlier quoted context omitted.

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 som…

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 func…

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.

Re: Zig's New Async I/O

#33

Earlier quoted context omitted.

mlugg is in the Zig core team

I'm aware, but Zig isn't a democracy where the core team votes, right? Has Andrew actually expressed that he wants the proposal? Without that we're left with scraps like this commit message where he seems ambivalent. https://github.com/ziglang/zig/commit/d6c90ceb04f8eda7c6b711... Andrew, I know you read these threads sometimes, give us a sign so I can go down the mountain with my stone tablets and tell the people whe…

we do build internal consensus before publishing articles like this one, or doing other public communication.

Re: Zig's New Async I/O

#35
post #26

I don't know Zig, but wouldn't such a change be a major breaking change where all prior Zig code doing Io wouldn't work anymore if upgraded?

Zig's not at 1.0 yet, so there's no stability guarantee at this point.

Re: Zig's New Async I/O

#36
post #14
post #3

I feel that I have to point this out once again, because the article goes so far as to state that: > With this last improvement Zig has completely defeated function coloring. I disagree with this. Let's look at the 5 rules referenced in the famous "What color is your function?" article referenced here. > 1. Every function has a color Well, you don't have async/sync/red/blue anymore, but you now have IO and non-IO fun…

Go also suffers from this form of “subtle coloring”. If you’re working with goroutines, you would always pass in a context parameter to handle cancellation. Many library functions also require context, which poisons the rest of your functions. Technically, you don’t have to use context for a goroutine and could stub every dependency with context.Background, but that’s very discouraged.

Context is not required in Go and I personally encourage you to avoid it. There is no shame in blazing a different path.

Re: Zig's New Async I/O

#37

Earlier quoted context omitted.

mlugg is in the Zig core team

I'm aware, but Zig isn't a democracy where the core team votes, right? Has Andrew actually expressed that he wants the proposal? Without that we're left with scraps like this commit message where he seems ambivalent. https://github.com/ziglang/zig/commit/d6c90ceb04f8eda7c6b711... Andrew, I know you read these threads sometimes, give us a sign so I can go down the mountain with my stone tablets and tell the people whe…

We don't know whether or not we'll have stackless coroutines; it's possible that we hit design problems we didn't foresee. However, at this moment, the general consensus is that we are interested in pursuing stackless coroutines.

While Andrew has the final say, as Loris points out, we always work to reach a consensus internally. The article lists this an an implementation that will probably exist, because we agree that it probably will; nobody is promising it, because we also agree that it isn't guaranteed.

Also, bear in mind that even if stackless coroutines don't make it into Zig, you can always use a single-threaded blocking implementation of `Io`, so you need not be negatively affected by any potential downsides to fibers either way.

This new `Io` approach has made it strictly more likely than it previously was that stackless coroutines become a part of Zig's final design.

Re: Zig's New Async I/O

#38
post #15

Seeing a systems language like Zig require runtime polymorphism for something as common as standard IO operations seems off to me -- why force that runtime overhead on everyone when the concrete IO implementation could be known statically in almost all practical cases?

I think it's just the Zig philosophy to care more about binary size than speed. Allocators have the same tradeoff, ArrayListUnmanaged is not generic over the allocator, so every allocation uses dynamic dispatch. In practice the overhead of allocating or writing a file will dwarf the overhead of an indirect call. Can't argue with those binary sizes. (And before anyone mentions it, devirtualization is a myth, sorry)

It can also mean faster compilation (and sometimes better performance? https://nical.github.io/posts/rust-custom-allocators.html)

Just templating everything doesn’t mean it will be faster every time

Re: Zig's New Async I/O

#39
> io.async expresses asynchronicity (the possibility for operations to happen out of order and still be correct) and it does not request concurrency, which in this case is necessary for the code to work correctly.

This is the key point for me. Regardless of whether you’re under an async event loop, you can specify that the order of your io calls does not imply sequencing. Brilliant. Separate what async means from what the io calls do.

Re: Zig's New Async I/O

#40
post #36
post #14

Earlier quoted context omitted.

Go also suffers from this form of “subtle coloring”. If you’re working with goroutines, you would always pass in a context parameter to handle cancellation. Many library functions also require context, which poisons the rest of your functions. Technically, you don’t have to use context for a goroutine and could stub every dependency with context.Background, but that’s very discouraged.

Context is not required in Go and I personally encourage you to avoid it. There is no shame in blazing a different path.

What would you use in its place? I've never had an issue with it. I use it for 1) early termination 2) carrying custom request metadata.

I don't really think it is fully the coloring problem because you can easily call non-context functions from context functions (but not other way around, so one way coloring issue), but you need to be aware the cancellation chain of course stops then.

Post reply on HN