Live data from Hacker News

Async/Await is finally back in Zig

charlesfonseca.substack.com

71–80 of 90 posts

Re: Async/Await is finally back in Zig

#71

Earlier quoted context omitted.

Losing threads and moving to the async I/O model was the motivation behind Node in the first place. https://nodejs.org/en/about

If you use async I/O you can just use the Chrome JavaScript runtime as-is. I would claim it was the only low-effort model available to them and therefore not motivation. The motivation for node was that users wanted to use JavaScript on the server.

> If you use async I/O you can just use the Chrome JavaScript runtime as-is.

What do you mean? A JS runtime can't do anything useful on its own, it can't read files, it can't load dependencies because it doesn't know anything about "node_modules", it can't open sockets or talk to the world in any other way - that's what Node.js provides.

> I would claim it was the only low-effort model available to them and therefore not motivation.

It was a headline feature when it released.

https://web.archive.org/web/20100901081015/https://nodejs.or...

Re: Async/Await is finally back in Zig

#72
post #36

Earlier quoted context omitted.

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

I have even simpler version:

https://github.com/lalinsky/zio/blob/main/src/coroutines.zig

Which has the benefit of Zig single unit of compilation, that the compiler can be smarter about which registers need to be saved.

Re: Async/Await is finally back in Zig

#73
post #47

Earlier quoted context omitted.

But if you explicitly handle exceptions using IF statements then that's overhead too, right?

yes but i think branch prediction essentialy makes them zero overhead

That's a different type of overhead than having unwind tables. With exceptions you wouldn't need a branch after each function call at all.

Re: Async/Await is finally back in Zig

#74

Earlier quoted context omitted.

What bothers me, for example in Python, with the function coloring is that it creeps everywhere and you need to rewrite your functions to accommodate async. I think being able to take and return futures or promises and handle them how you wish is better ergonomics.

> I think being able to take and return futures or promises and handle them how you wish is better ergonomics. You can do that. If you don't await an async call, you have a future object that you can handle however you want.

Yeah but to be fair, that can have adverse effects if you, say, busy wait.

The sync code might be running in an async context. Your async context might only have one thread. The task you're waiting for can never start because the thread is waiting for it to finish. Boom, you're deadlocked.

Async/await runtimes will handle this because awaiting frees the thread. So, the obvious thing to do is to await but then it gets blamed for being viral.

Obviously busy waiting in a single threaded sync context will also explode tho...

Re: Async/Await is finally back in Zig

#75
post #73

Earlier quoted context omitted.

yes but i think branch prediction essentialy makes them zero overhead

That's a different type of overhead than having unwind tables. With exceptions you wouldn't need a branch after each function call at all.

But a branch that is (almost) never taken has an overhead close to the overhead of a NOP instruction, which may be negligible on modern architectures.

Re: Async/Await is finally back in Zig

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

In single threaded scripting languages, it has arisen as a way to allow overlapping computation with communication without having to introduce multi threading and dealing with the fact that memory management and existing code in the language aren't thread-safe. In other languages it seems to be used as a away to achieve green threading with an opt-in runtime written as a library within the language rather than doing…

Agreed. Async I/O is something where letting the runtime keep track of it for you doesn't incur any more overhead, unlike garbage collection, and that makes for a much more natural programming pseudo-synchronous.

Re: Async/Await is finally back in Zig

#77
post #17

Earlier quoted context omitted.

Concur. I build my own tools in rust when I have to just to avoid it. It is splitting rust into 2 ecosystems, and I wish it didn't exist because it's a big compatibility barrier. We should be moving towards fewer of these; not more. Make code and applications easier to interop; Async makes it more difficult.

I can't stand this aversion to async/await. It's not a big deal. I don't understand why async code is being treated as dangerous or as rocket science. You still maintain complete control, and it's straightforward. Now that we know about the "futurelock" issue, it will be addressed. I'm sure Rust and the cargo/crates ecosystem will even grow the ability to mark crates as using async so if you really care to avoid them…

Because async Rust is a lot harder to reason about than sync code. And I want my code to be as easy to reason about as possible.

Re: Async/Await is finally back in Zig

#78

Earlier quoted context omitted.

If you use async I/O you can just use the Chrome JavaScript runtime as-is. I would claim it was the only low-effort model available to them and therefore not motivation. The motivation for node was that users wanted to use JavaScript on the server.

> If you use async I/O you can just use the Chrome JavaScript runtime as-is. What do you mean? A JS runtime can't do anything useful on its own, it can't read files, it can't load dependencies because it doesn't know anything about "node_modules", it can't open sockets or talk to the world in any other way - that's what Node.js provides. > I would claim it was the only low-effort model available to them and therefore…

Obviously you can add modules calling to C/C++ functionality to a scripting language runtime easily (and the interface to do that is already available for the browser implementation).

In the above link Node could be described as a Chrome V8 distribution with modules enabling building a web server.

Adding threading to a non-threaded scripting runtime is another ball game.

The point is that Node was forced into this model by V8 limitations, then sold it as an advantage, however, it is only one way to solve the problem with its own trade-offs and you have to look at the specific use case you are looking at to see if it is really the best solution for your use case.

Re: Async/Await is finally back in Zig

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

The classic use case for async was applications with extreme I/O intensity, like high-end database engines. If designed correctly it is qualitatively higher performance than classic multithreading. This is the origin of async style.

Those large performance gains do not actually come from async style per se, which is where people become confused.

What proper async style allows that multithreading does not is that you can design and implement sophisticated bespoke I/O and execution schedulers for your application. Almost all the performance gains are derived from the quality of the custom scheduling.

If you delegate scheduling to a runtime, it almost completely defeats the point of writing code in async style.

Re: Async/Await is finally back in Zig

#80
post #36

Earlier quoted context omitted.

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?

That requires some explanation. Basically I think runtimes should be abort safe and have some defined thing that happens when a thread is aborted. Antiquated 70s blocking APIs do not, or do not consistently.

It’s a minor gripe compared to the heaviness of threads and making every programmer hand roll fibers by way of async.

Post reply on HN