Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

One of the biggest advantages of await is that it's explicit. Otherwise literally any function call can block, and whether or not it blocks is dependent on the body of the function so you can end up with races appearing in random parts of your code because you update a package. It's bad. At that point you might as well just use threads and blocking calls.


Data races like that can only happen when you share mutable state across logical flows of control. Don't share mutable state, regardless of your concurrency framework. I don't see how explicit vs implicit yield points change this fact. Either way there's precisely one logical flow of control that should own your data. In a language like Rust this is strongly enforced, regardless.

Futhermore, in any complex asynchronous I/O app most functions will end up being tagged async. The only ones that won't are simple leaf functions that wouldn't implicitly yield, anyhow. If someone has the bad idea to, e.g., put a yield point in non-obvious leaf functions as part of some kind of hack (e.g. logging, tracing), they're gonna do it in the async/await case, too, because they're already convinced it has value. Having to a drop a few more annotations here or there won't stop them from breaking the app.

Lastly, the bugs that do occur in these sorts of cases usually have to do with unpredictable latencies violating implicit or accidental ordering assumptions. async/await doesn't mitigate that at all because latencies are just as unpredictable. The solution, as always, is to avoid these ordering dependencies by not sharing mutable state.

This defense of async/await is a red herring.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: