Live data from Hacker News

Async/Await is finally back in Zig

charlesfonseca.substack.com

61–70 of 90 posts

Re: Async/Await is finally back in Zig

#61
post #6
post #4

Earlier quoted context omitted.

What is wrong about C++ exceptions?

For one thing, they’re expensive and viral. “Zero overhead” implementations don’t take into account the need for unwind tables. For every function/method that might be thrown across. They’re disabled in a lot of production environments for this reason.

There was an interesting talk about C++ exceptions in smaller firmware at CppCon last year: https://youtu.be/bY2FlayomlE

Basically, the overhead of exceptions is probably less than handling the same errors manually in any non-trivial program.

Also, it's not like these table doesn't exist in other languages. Both Rust and Go have to unwind.

Re: Async/Await is finally back in Zig

#62
post #36
post #13

Someone has historical insights into why async/await seems to have taken over the world? I often write Rust and I don't find it very attractive, but so many good projects seem to advertise it as a "killer feature". Diesel.rs doesn't have async, and they claim that perf improvement may not be worth it ( https://users.rust-lang.org/t/why-use-diesel-when-its-not-as... ). For a single threaded JS program, async makes a l…

I think it’s a terrible complexity multiplying workaround for the fact that we can’t fix our ancient 1970s OS APIs. Threads should be incredibly cheap. I should be able to launch them by the tens of millions, kill them at will, and this should be no more costly than goroutines. (All modern OSes in common use are 1970s vintage under the hood. All Unix is Bell Labs Unix with some modernization and veneer, and NT is VMS…

You don't need a fat runtime to do fibers/stackful coroutines. You don't need any language support for that matter, just 50 lines of assembly to save registers on the stack and switch stack pointers. Minicoro [1] is a C library that implements fibers in a single header (just the creation/destruction/context switching, you have to bring your own scheduler).

Our game engine has a in-house implementation - creating a fiber, scheduling it, and waiting for it to complete takes ~300ns on my box. Creating a OS thread and join()ing is just about 1000 slower, ~300us.

[1] https://github.com/edubart/minicoro

Re: Async/Await is finally back in Zig

#63

> Despite the completion order varying, each task correctly writes to its designated position in the results array, showing proper concurrent data handling. Huh? It’s not like the entire array was passed into each task. Each task just received a pointer to an usize to write to. Where is concurrent data writing in the example?

The requests were made concurrently. I don't understand your question. Passing in an array or a pointer does not matter.

Re: Async/Await is finally back in Zig

#64

Earlier quoted context omitted.

https://en.wikipedia.org/wiki/C10k_problem Because when you require 1 thread per 1 connection, you have trouble getting to thousands of active connections and people want to scale way beyond that. System threads have overhead that makes them impractical for this use case. The alternatives are callbacks, which everybody hates and for a good reason. Then you have callbacks wrapped by Futures/Promises. And then you have…

> The alternatives are callbacks, which everybody hates and for a good reason. Then you have callbacks wrapped by Futures/Promises. And then you have some form of coroutines. The event loop model is arguably equivalent to coroutines. Just replace yield with return and have the underlying runtime decide which functions to call next by looping through them in a list. You can even stall the event loop and increase laten…

Coroutines/resumable functions are not restricted to yielding to a single runtime or event loop, they can simply "resume" each other directly. There are also extensions of coroutines that are more than one-shot (a resumable function where the current state can be copied and invoked more than once) and/or are allowed to provide values when "resuming" other code, which also goes beyond the common "event loop" model.

Re: Async/Await is finally back in Zig

#65
I wrote my shell prompt in Zig years ago in part because I was interested to use its async/await to run all the git calls in parallel for the git status. My prompt is still fast despite never having parallelized things -- slightly slower now after adding Jujutsu status -- but I'm looking forward to getting to do the thing I originally wanted and have my super fast shell prompt.

To speak to the Zig feature: as a junior I kept bugging the seniors about unit testing and how you were supposed to test things that did IO. An explanation of "functional core imperative shell" would have been helpful, but their answer was: "wrap everything in your own classes, pass them everywhere, and provide mocks for testing". This is effectively what Zig is doing at a language level.

It always seemed wrong to me to have to wrap your language's system libraries so that you could use them the "right way" that is testable. It actually turns out that all languages until Zig have simply done it wrong, and IO should be a parameter you pass to any code that needs it to interact with the outside world.

Re: Async/Await is finally back in Zig

#66
post #36
post #13

Someone has historical insights into why async/await seems to have taken over the world? I often write Rust and I don't find it very attractive, but so many good projects seem to advertise it as a "killer feature". Diesel.rs doesn't have async, and they claim that perf improvement may not be worth it ( https://users.rust-lang.org/t/why-use-diesel-when-its-not-as... ). For a single threaded JS program, async makes a l…

I think it’s a terrible complexity multiplying workaround for the fact that we can’t fix our ancient 1970s OS APIs. Threads should be incredibly cheap. I should be able to launch them by the tens of millions, kill them at will, and this should be no more costly than goroutines. (All modern OSes in common use are 1970s vintage under the hood. All Unix is Bell Labs Unix with some modernization and veneer, and NT is VMS…

"Threads" are expensive because they are OS-managed "virtual" cores as seen by the current process. You can run coroutines as "user-level" tasks on top of kernel threads, and both Go and Rust essentially allow this, though in slightly different ways.

Re: Async/Await is finally back in Zig

#67
post #22

Earlier quoted context omitted.

https://en.wikipedia.org/wiki/C10k_problem Because when you require 1 thread per 1 connection, you have trouble getting to thousands of active connections and people want to scale way beyond that. System threads have overhead that makes them impractical for this use case. The alternatives are callbacks, which everybody hates and for a good reason. Then you have callbacks wrapped by Futures/Promises. And then you have…

> The alternatives are callbacks No. The alternative is lightweight/green threads and actors. The thing with await is that it can be retrofitted onto existing languages and runtimes with relatively little effort. That is, it's significantly less effort than retrofitting an actual honest-to-god proper actor system a la Erlang.

> The alternative is lightweight/green threads and actors.

Those are all some form of coroutines.

Re: Async/Await is finally back in Zig

#68

Earlier quoted context omitted.

https://en.wikipedia.org/wiki/C10k_problem Because when you require 1 thread per 1 connection, you have trouble getting to thousands of active connections and people want to scale way beyond that. System threads have overhead that makes them impractical for this use case. The alternatives are callbacks, which everybody hates and for a good reason. Then you have callbacks wrapped by Futures/Promises. And then you have…

> The alternatives are callbacks, which everybody hates and for a good reason. Then you have callbacks wrapped by Futures/Promises. And then you have some form of coroutines. The event loop model is arguably equivalent to coroutines. Just replace yield with return and have the underlying runtime decide which functions to call next by looping through them in a list. You can even stall the event loop and increase laten…

It's all the same concept, it's just a matter who/what is managing the state while you are waiting for I/O. When you yield, it's the compiler/runtime making sure the context is saved. When you return, it's your responsibility.

Re: Async/Await is finally back in Zig

#69
post #36
post #13

Someone has historical insights into why async/await seems to have taken over the world? I often write Rust and I don't find it very attractive, but so many good projects seem to advertise it as a "killer feature". Diesel.rs doesn't have async, and they claim that perf improvement may not be worth it ( https://users.rust-lang.org/t/why-use-diesel-when-its-not-as... ). For a single threaded JS program, async makes a l…

I think it’s a terrible complexity multiplying workaround for the fact that we can’t fix our ancient 1970s OS APIs. Threads should be incredibly cheap. I should be able to launch them by the tens of millions, kill them at will, and this should be no more costly than goroutines. (All modern OSes in common use are 1970s vintage under the hood. All Unix is Bell Labs Unix with some modernization and veneer, and NT is VMS…

Kill threads at will?

Re: Async/Await is finally back in Zig

#70
post #41
post #18

Earlier quoted context omitted.

C# had async/await long before Javascript/node. Not that big a revelation ;-)

.NET wasn't the first either. Lisps were doing continuations in the 70's. But "invented" and "revealed" are different verbs for a reason. The release of node.js and it's pervasively async architecture changed the way a lot of people thought about how to write code. For the better in a few ways. But the resulting attempt to shoe-horn the paradigm into legacy and emerging environments that demanded it live in a shared…

I think you're underestimating the role of .NET in this. It was .NET that popularized this concept for the masses, and from there it spread to other languages including JavaScript, which also borrowed the exact same async/await keywords from C#.
Post reply on HN