Most active commenters
  • luke5441(5)
  • dns_snek(4)

←back to thread

Async/Await is finally back in Zig

(charlesfonseca.substack.com)
39 points barddoo | 13 comments | | HN request time: 0s | source | bottom
Show context
ajross ◴[] No.45782414[source]
Is it time now to say that async was a mistake, a-la C++ exceptions? The recent futurelock discussion[1] more or less solidified for me that this is all just a mess. Not just that one bug, but the coloring issue mentioned in the blog post (basically async "infects" project code requiring that you end up porting or duplicating almost everything -- this is especially true in Python). The general cognitive load of debugging inside out code is likewise really high, even if the top-level expression of the loop generator or whatever is clean.

And it's all for, what? A little memory for thread stacks (most of which ends up being a wash because of all the async contexts being tossed around anyway -- those are still stacks and still big!)? Some top-end performance for people chasing C10k numbers in a world that has scaled into datacenters for a decade anyway?

Not worth it. IMHO it's time to put this to bed.

[1] No one in that thread or post has a good summary, but it's "Rust futures consume wakeup events from fair locks that only emit one event, so can deadlock if they aren't currently being selected and will end up waiting for some other event before doing so."

replies(5): >>45782432 #>>45782502 #>>45782558 #>>45782647 #>>45782786 #
jayd16 ◴[] No.45782502[source]
I really wish people would get over the coloring meme.

Knowing if a function will yield the thread is actually extremely relevant knowledge you want available.

replies(8): >>45782525 #>>45782537 #>>45782580 #>>45782601 #>>45782790 #>>45782846 #>>45782853 #>>45782877 #
pton_xd ◴[] No.45782525[source]
Look at the node.js APIs: readFile, readFileSync, writeFile, writeFileSync ... and on and on. If that's not a meme then I don't know what is.
replies(1): >>45782549 #
1. rafaelmn ◴[] No.45782549[source]
And the alternative without async-await is ? blocking the event loop or the callback pyramid.

Node is one place where async-await has zero counter arguments and every alternative is strictly worse.

replies(3): >>45782668 #>>45782941 #>>45782999 #
2. luke5441 ◴[] No.45782668[source]
They could have added threads to Node as well? Granted, it would have been a lot of difficult work.
replies(2): >>45782774 #>>45782795 #
3. jayd16 ◴[] No.45782774[source]
You mean like with web workers or something?
replies(1): >>45782864 #
4. dns_snek ◴[] No.45782795[source]
Losing threads and moving to the async I/O model was the motivation behind Node in the first place.

https://nodejs.org/en/about

replies(1): >>45782903 #
5. luke5441 ◴[] No.45782864{3}[source]
With a shared interpreter/process state, like Python, Java, C, C++, ...

Node is not a web page, so no reason to limit it to the same patterns.

Then, the next issue would be thread safety. But that could be treated as a separate problem.

6. luke5441 ◴[] No.45782903{3}[source]
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.

replies(1): >>45783239 #
7. ojosilva ◴[] No.45782941[source]
The problem with Node is that the async decision is in the hand of the leaf node, which bubbles up to the parent where my code sits. Async/await is nice and a goal in most modern Node, but there are codebases (old and new) where async/await is just not an option for many reasons.

Node dictates that when faced with an async function the result is that I must either implement async myself so I can do await or go into callback rabbit holes by doing .then(). If the function author is nice, they will give me both async and sync versions: readFile() and readFileSync(). But that sucks.

The alternative would be that 1) the decision to go async were mine; 2) the language supports my decision with syntax/semantics.

Ie. if I call the one and only fs.readFile() and want to block I would then do

       sync fs.readFile()
Node would take care of performing a nice synchronous call that is beneficial to its event-loop logic and callback pyramid. End of the story. And not some JS an implementation such as deasync [1] but in core Node.

1. https://www.npmjs.com/package/deasync

8. ajross ◴[] No.45782999[source]
> And the alternative without async-await is ? blocking the event loop or the callback pyramid.

No, just callbacks and event handlers (and an interface like select/poll/epoll/kqueue for the OS primitives on which you need to wait). People were writing threadless non-blocking code back in the 80's, and while no one loved the paradigm it was IMHO less bad than the mess we've created trying to avoid it.

One of the problems I'm trying to point out is that we're so far down the rabbit hole in this madness that we've forgotten the problems we're actually trying to solve. And in particular we've forgotten that they weren't that hard to begin with.

9. dns_snek ◴[] No.45783239{4}[source]
> 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...

replies(1): >>45783896 #
10. luke5441 ◴[] No.45783896{5}[source]
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.

replies(1): >>45784739 #
11. dns_snek ◴[] No.45784739{6}[source]
> Obviously you can add modules calling to C/C++ functionality to a scripting language runtime easily

Yes, obviously, that's what NodeJS does. But you can't "just use the V8 runtime as-is if you're doing async IO", it doesn't have those facilities at all.

Async IO wasn't just "sold as an advantage", it is an advantage. Websockets were gaining popularity around that time and async IO is a natural fit for that.

You would have to change the language and boil the ocean to make the runtime support multiple threads (properly).

But why? Just to end up with the inferior thread-per-request runtime (which by the way, still needs to support async because it's part of the language), that requires developers to write JS which is incompatible with browser JS, which would've eliminated most of the synergy between the two?

I really don't understand what you're going for here. I don't see a single advantage here.

replies(1): >>45786384 #
12. luke5441 ◴[] No.45786384{7}[source]
I think green threads (Java Virtual Threads, Go to an extent) are strictly superior to async/await.

If you don't have many threads, OS threads are okay as well. It is all about memory and scheduling overhead.

But that is just my opinion. You are welcome to have a different opinion.

replies(1): >>45797280 #
13. dns_snek ◴[] No.45797280{8}[source]
No I don't think your opinion is "wrong" or anything, it's just that this is a language-level limitation and not a valid criticism of NodeJS.