Live data from Hacker News

Zig's new plan for asynchronous programs

lwn.net

21–30 of 274 posts

Re: Zig's new plan for asynchronous programs

#21
post #13

Earlier quoted context omitted.

In my (Rust-colored) opinion, the async keyword has two main problems: 1) It tracks code property which is usually omitted in sync code (i.e. most languages do not mark functions with "does IO"). Why IO is more important than "may panic", "uses bounded stack", "may perform allocations", etc.? 2) It implements an ad-hoc problem-specific effect system with various warts. And working around those warts requires re-imple…

> Why IO is more important than "may panic", "uses bounded stack", "may perform allocations", etc.? Rust could use these markers as well.

I agree. But it should be done with a proper effect system, not a pile of ad hoc hacks built on abuse of the type system.

Re: Zig's new plan for asynchronous programs

#22
I think this design is very reasonable. However, I find Zig's explanation of it pretty confusing: they've taken pains to emphasize that it solves the function coloring problem, which it doesn't: it pushes I/O into an effect type, which essentially behaves as a token that callers need to retain. This is a form of coloring, albeit one that's much more ergonomic.

(To my understanding this is pretty similar to how Go solves asynchronicity, expect that in Go's case the "token" is managed by the runtime.)

Re: Zig's new plan for asynchronous programs

#24
I like Zig and I like their approach in this case.

From the article:

    std.Io.Threaded - based on a thread pool.

      -fno-single-threaded - supports concurrency and cancellation.
      -fsingle-threaded - does not support concurrency or cancellation.

    std.Io.Evented - work-in-progress [...]
Should `std.Io.Threaded` not be split into `std.Io.Threaded` and `std.Io.Sequential` instead? Single threaded is another word for "not threaded", or am I wrong here?

Re: Zig's new plan for asynchronous programs

#25
post #14
post #4

I’m excited to see how this turns out. I work with Go every day and I think Io corrects a lot of its mistakes. One thing I am curious about is whether there is any plan for channels in Zig. In Go I often wish IO had been implemented via channels. It’s weird that there’s a select keyword in the language, but you can’t use it on sockets.

One of the harms Go has done is to make people think its concurrency model is at all special. “Goroutines” are green threads and a “channel” is just a thread-safe queue, which Zig has in its stdlib https://ziglang.org/documentation/master/std/#std.Io.Queue

What other mainstream languages have pre-emptive green threads without function coloring? I can only think of Erlang.

Re: Zig's new plan for asynchronous programs

#26
I find this example quite interesting:

       var a_future = io.async(saveFile, .{io, data, "saveA.txt"});
        var b_future = io.async(saveFile, .{io, data, "saveB.txt"});

        const a_result = a_future.await(io);
        const b_result = b_future.await(io);
In Rust or Python, if you make a coroutine (by calling an async function, for example), then that coroutine will not generally be guaranteed to make progress unless someone is waiting for it (i.e. polling it as needed). In contrast, if you stick the coroutine in a task, the task gets scheduled by the runtime and makes progress when the runtime is able to schedule it. But creating a task is an explicit operation and can, if the programmer wants, be done in a structured way (often called “structured concurrency”) where tasks are never created outside of some scope that contains them.

From this example, if the example allows the thing that is “io.async”ed to progress all by self, then I guess it’s creating a task that lives until it finishes or is cancelled by getting destroyed.

This is certainly a valid design, but it’s not the direction that other languages seem to be choosing.

Re: Zig's new plan for asynchronous programs

#27

> Languages that don't make a syntactical distinction (such as Haskell) essentially solve the problem by making everything asynchronous What the heck did I just read. I can only guess they confused Haskell for OCaml or something; the former is notorious for requiring that all I/O is represented as values of some type encoding the full I/O computation. There's still coloring since you can't hide it, only promote it to…

Haskell has green threads. Plus nowadays Java also has virtual threads.

Re: Zig's new plan for asynchronous programs

#28

I think this design is very reasonable. However, I find Zig's explanation of it pretty confusing: they've taken pains to emphasize that it solves the function coloring problem, which it doesn't: it pushes I/O into an effect type, which essentially behaves as a token that callers need to retain. This is a form of coloring, albeit one that's much more ergonomic. (To my understanding this is pretty similar to how Go sol…

Having used zig a bit as a hobby. Why is it more ergonomic? Using await vs passing a token have similar ergonomics to me. The one thing you could say is that using some kind of token makes it dead simple to have different tokens. But that's really not something I run into often at all when using async.

Re: Zig's new plan for asynchronous programs

#29
post #27

> Languages that don't make a syntactical distinction (such as Haskell) essentially solve the problem by making everything asynchronous What the heck did I just read. I can only guess they confused Haskell for OCaml or something; the former is notorious for requiring that all I/O is represented as values of some type encoding the full I/O computation. There's still coloring since you can't hide it, only promote it to…

Haskell has green threads. Plus nowadays Java also has virtual threads.

And I bet those green threads still need an IO type of some sort to encode anything non-pure, plus usually do-syntax. Comparing merely concurrent computations to I/O-async is just weird. In fact, I suspect that even those green threads already have a "colourful" type, although I can't check right now.

Re: Zig's new plan for asynchronous programs

#30
post #26

I find this example quite interesting: var a_future = io.async(saveFile, .{io, data, "saveA.txt"}); var b_future = io.async(saveFile, .{io, data, "saveB.txt"}); const a_result = a_future.await(io); const b_result = b_future.await(io); In Rust or Python, if you make a coroutine (by calling an async function, for example), then that coroutine will not generally be guaranteed to make progress unless someone is waiting f…

This is how JS works
Post reply on HN