Live data from Hacker News

What async promised and what it delivered

causality.blog

181–190 of 317 posts

Re: What async promised and what it delivered

#181

The discussion around async await always focuses on asynchronous use-cases, but I see the biggest benefits when writing synchronous code. In JS, not having await in front of a statement means that nothing will interfere with your computation. This simplifies access to shared state without race conditions. The other advantage is a rough classification in the type system. Not marking a function as async means that the…

Maybe I am missing something. But the function coloring problem is basically the tension that async can dominate call hierarchies and the sync code in between looses it's beneficial properties to a degree. It's at least awkward to design a system that smoothly tries to blend sync that executes fast and async code that actually requires it. Saying that fs.readSync shouldn't exist is really weird. Not all code written…

'readSync' does two different things - tells the OS we want to read some data and then waits for the data to be ready.

In a good API design, you should exposed functions that each do one thing and can easily be composed together. The 'readSync' function doesn't meet that requirement, so it's arguably not necessary - it would be better to expose two separate functions.

This was not a big issue when computers only had a single processor or if the OS relied on cooperative multi-threading to perform I/O. But these days the OS and disk can both run in parallel to your program so the requirement to block when you read is a design wart we shouldn't have to live with.

Re: What async promised and what it delivered

#182

Earlier quoted context omitted.

10 GB of RAM is certainly something though. Especially in current times.

Except if those threads are actually faulting in all of that memory and making it resident, they'd be doing the same thing, just on the heap, for a classic async coroutine style application.

If you have hugepages enabled, all of those threads are probably faulting in a fair amount of memory.

Re: What async promised and what it delivered

#183
post #142
post #112

Earlier quoted context omitted.

Server applications don’t spawn threads per request, they use thread pools. The extra context switching due to threads waiting for I/O is negligible in practice for most applications. Asynchronous I/O becomes important when the number of simultaneous requests approaches the number of threads you can have on your system. Many applications don’t come close to that in practice. There’s a benefit in being able to code th…

There’s also a really good operational benefit if you have limits like total RAM, database connections, etc. where being able to reason about resource usage is important. I’ve seen multiple async apps struggle with things like that because async makes it harder to reason about when resources are released.

Could you point out the issue here?

Why does async make it harder to reason about when resources are released?

Re: What async promised and what it delivered

#184
I’m not really smart on this subject but I started during callback hell and now use async in Node and front-end and I find it to be just superb. Sometimes I have to reason about queued tasks vs. micro tasks and all that but most of the time it just does what I expect and keeps the code very clean.

Re: What async promised and what it delivered

#187
post #87

> Language designers who studied the async/await experience in other ecosystems concluded that the costs of function coloring outweigh the benefits and chose different paths. Not really. The author provides Go as evidence, but Go's CSP-based approach far predates the popularity of async/await. Meanwhile, Zig's approach still has function coloring, it's just that one color is "I/O function" and the other is "non-I/O f…

In my experience people complain about it because they are coming from a blocking first mindset. They're trying to shoehorn async calls into an inherently synchronous structure. A while back I just started leaning in. I write a lot of Python at work, and anytime I have to use a library that's relies on asyncio, I just write the entire damn app as an asynchronous one. Makes function coloring a non-issue. If I'm in a s…

> Makes function coloring a non-issue.

Yes, having to rewrite literally all of your code because you need to use an async function somewhere is an issue.

An even bigger issue is that now you have two (incompatible!) versions of literally every library dependency.

Re: What async promised and what it delivered

#188

Earlier quoted context omitted.

I knew someone was going to bring up monads that's why I put JS version :) JS took the C# syntax.

Similarly F#'s computation expressions predate C#'s syntax, and there is some evidence that C# language designers were looking at F#'s computation expressions. Since the Linq work, C# has been very aware of Monads, and very slow and methodical about how it approaches them. Linq syntax is a subtly compromised computation expression and async/await is a similar compromise. It's interesting to wonder about the C# world…

> use async/await syntax for arbitrary monads. (In JS, it is even easier to bend async/await to arbitrary monads given the rules of a "thenable" are real simple.)

I tried once to hack list comprehensions into JS by abusing async/await. You can monkey patch `then` onto Array and define it as flatMap and IIRC you can indeed await arrays that way, but the outer async function always returns a regular Promise. You can't force it to return an instance of the patched Array type.

Re: What async promised and what it delivered

#189
post #181

Earlier quoted context omitted.

Maybe I am missing something. But the function coloring problem is basically the tension that async can dominate call hierarchies and the sync code in between looses it's beneficial properties to a degree. It's at least awkward to design a system that smoothly tries to blend sync that executes fast and async code that actually requires it. Saying that fs.readSync shouldn't exist is really weird. Not all code written…

'readSync' does two different things - tells the OS we want to read some data and then waits for the data to be ready. In a good API design, you should exposed functions that each do one thing and can easily be composed together. The 'readSync' function doesn't meet that requirement, so it's arguably not necessary - it would be better to expose two separate functions. This was not a big issue when computers only had…

> tells the OS we want to read some data and then waits for the data to be ready

No, it tells the OS "schedule the current thread to wake up when the data read task is completed".

Having to implement that with other OS primitives is a) complex and error-prone, and b) not atomic.

Re: What async promised and what it delivered

#190
post #100
post #39

How many systems are there that can't just spawn a thread for each task they have to work on concurrently? This has to be a system that is A) CPU or memory bound (since async doesn't make disk or network IO faster) and B) must work on ~tens of thousands of tasks concurrently, i.e. can't just queue up tasks and work on only a small number concurrently. The only meaningful example I can come up with are load balancers,…

Pretty much anything that needs performance and has a lot of relatively light operations is not a candidate for spawning a thread. Context switching and the cost of threads is going to kill performance. A server spawning a thread per request for relatively lightweight request is going to be extremely slow. But sure, if every REST call results in a 10s database query then that's not your bottleneck. A query to a datab…

> Context switching

No such thing. In a preemptive multitasking OS (that's basically all of them today) you will get context switching regardless of what you do. Most modern OS's don't even give you the tools to mess with the scheduler at all; the scheduler knows best.

Post reply on HN