Live data from Hacker News

Zig's New Async I/O

kristoff.it

151–160 of 293 posts

Re: Zig's New Async I/O

#151
post #24

Earlier quoted context omitted.

> It's quite rare for a function to unexpectedly gain a dependency on ... If this was true in general, the function coloring problem wouldn't be talked about. However, the second point is more interesting. I think there's a bit of a Stockholm syndrome thing here with Zig programmers and Allocator. It's likely that Zig programmers won't mind passing around an extra param. If anything, it would make sense to me to have…

> If anything, it would make sense to me to have IO contain an allocator too. Allocation is a kind of IO too. Io in zig is for “things that can block execution”. Things that could semantically cause a yield of any kind. Allocation is not one of those things. Also, it’s perfectly reasonable and sometimes desireable to have 13 different allocators in your program at once. Short lived ones, long lived ones, temporary al…

> Io in zig is for “things that can block execution”. Things that could semantically cause a yield of any kind. Allocation is not one of those things.

The allocator may yield to the OS when requesting or releasing memory (e.g. sbrk, mmap, munmap)?

Re: Zig's New Async I/O

#152
post #20

Earlier quoted context omitted.

> but most modern apps rely on some form of dependency injection Does Zig actually do anything here? If anything, this seems to be anti-Zig, where everything must be explicit.

Passing in your dependencies as function arguments is a form of dependency injection. It is the simplest and thus arguably best form of dependency injection.

This is like saying arithmetic is a form of calculus, the simplest form. Ie it reduces the concept (DI) to a meaningless tautology.

Re: Zig's New Async I/O

#153
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…

So this is a tangent from the main article, but this comment made me curious and I read the original "What color is Your Function" post. It was an interesting read, but I guess I came away confused about why "coloring" functions is a problem. Isn't "coloring" just another form of static typing? By giving the compiler (or interpreter) more meta data about your code, it can help you avoid mistakes. But instead of the u…

Yes, the main character of that article really is mostly JavaScript. The main issue there is that some things must be async, and that doesn't mesh well with things that can't be.

If you're writing a game, and you need to render a new enemy, you might want to reduce performance by blocking rather than being shot by an invisible enemy because you can only load the model async.

But even the article acknowledges that various languages tackle this problem better. Zig does a good job, but claiming it's been defeated completely doesn't really fly for me.

Re: Zig's New Async I/O

#154
post #144
post #30

Earlier quoted context omitted.

You’re allowed to not like it, but that doesn’t change that your argument that this is a form of coloring is objectively false. I’m not sure what Rust has to do with it.

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);

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.

Re: Zig's New Async I/O

#155
I think this design is a regression from the previous design, in which you could use compile time introspection to check whether things are actually async (calling convention) or not.

Additionally, I don't necessarily want to delegate the management of the memory backing the futures to an Io, or pass around a blob of syscalls and an associated runtime, which accesses everything via a vtable. I would prefer to have these things be compile time generic only.

Re: Zig's New Async I/O

#156

Earlier quoted context omitted.

> If anything, it would make sense to me to have IO contain an allocator too. Allocation is a kind of IO too. Io in zig is for “things that can block execution”. Things that could semantically cause a yield of any kind. Allocation is not one of those things. Also, it’s perfectly reasonable and sometimes desireable to have 13 different allocators in your program at once. Short lived ones, long lived ones, temporary al…

> Io in zig is for “things that can block execution”. Things that could semantically cause a yield of any kind. Allocation is not one of those things. The allocator may yield to the OS when requesting or releasing memory (e.g. sbrk, mmap, munmap)?

I don't find that a particularly compelling argument in this case, because so can accessing any memory address if it's not currently swapped in.

Re: Zig's New Async I/O

#157
post #123

Earlier quoted context omitted.

> If anything, it does a great job at abstracting the usage from the implementation. This is something Rust fails at spectacularly. Could you expand on this? I don't get what you mean

I am not very experienced in async Rust, but it seems there are some pieces of async Rust that rely too much on tokio internals, so using an alternative runtime (like pollster) results in broken code. Searching for comments mentioning "pollster" and "tokio" on HN brings a few results, but not one I recall seeing a while ago where someone demonstrated an example of a library (using async Rust) that crashes when not us…

[deleted]

Re: Zig's New Async I/O

#158
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…

So this is a tangent from the main article, but this comment made me curious and I read the original "What color is Your Function" post. It was an interesting read, but I guess I came away confused about why "coloring" functions is a problem. Isn't "coloring" just another form of static typing? By giving the compiler (or interpreter) more meta data about your code, it can help you avoid mistakes. But instead of the u…

I believe the point is less about "coloring" not having value as a type-system feature, and more about its bad ergonomics, and its viral nature in particular.

Re: Zig's New Async I/O

#160
post #120

Earlier quoted context omitted.

You are skipping the massive point here. If you are using a library in rust, it has to be async await, tokio, send+sync and all the other crap. Or if it is sync api then it is useless for async application. This approach of passing IO removes this problem and this is THE main problem. This way you don’t have to use procedural macros or other bs to implement multi versioning for the functions in your library, which do…

> If you are using a library in rust, it has to be async await, tokio, send+sync and all the other crap Send and sync is only required if you want to access something from multiple threads, which isn't required by async await (parallelism vs concurrency) 1) You can use async await without parallelism and 2) send and sync aren't a product of async/await in Rust, but generally memory safety, i.e. you need Send generall…

Yes, but async Rust is basically built on tokio's runtime, which is what most the big async libraries depend on, like hyper/axum/tokio etc. And tokio is a thread-per-core work-stealing architecture, which requires Send + Sync bounds everywhere. You can avoid them if you depend on tokio-proper, but it's more icky when building on something like axum, where your application handlers also require these bounds.

A good article on this: https://emschwartz.me/async-rust-can-be-a-pleasure-to-work-w...

Post reply on HN