Hacker News new | ask | show | jobs
by thom 1233 days ago
I actually think async/await is a terrible primitive, and if you’re on Java, the approach of Project Loom is vastly superior (i.e. threads can be cheap so everything can just be synchronous again). I’ve no problem with library-level concepts like promises and futures but it feels very short sighted to put it into an actual language, it’s just noise.
2 comments

Why don't you like async/await?

8 years ago I wrote a npm package that turned code that looks like this:

    tcp.send("syn", function(syn) {
        console.log("received", syn);
        tcp.send("syn-ack", function(synack) {
          console.log("received", synack);
          tcp.send("ack", function(ack) {
            console.log("received", ack);
         });
     });
   });
into this:

  seq([tcp, console], function(tcp, console) {
    var syn = {}; var synack = {}; var ack = {};
    tcp.send("syn", this(syn));
    console.log("received %s", syn);
    tcp.send("syn-ack", this(synack));
    console.log("received %s", synack); 
    tcp.send("ack", this(ack));
    console.log("received %s", ack); 
  });
it was never ready for production use, but it showed that synchronous code illusion can be created from callbacks.

How would you prefer to write asynchronous code?

How does Loom handle resource starvation problem? If a thread puts a while (true) {} in there somewhere, can that thread be preempted away from that kernel thread?

I think async/await is just noise: if you already have a heavy runtime like JavaScript or Python does (I forgive Rust for this one because it's so tied to reducing runtime overhead), you might as well handwave the distinction between green threads and system threads away and just pretend all asynchronous calls are synchronous (e.g. like how the eventlet or the Go runtime do it): it's painful when you have to call an asynchronous function from a synchronous context!

If you put while (true) { } in an asynchronous function, wouldn't you also have a resource starvation problem? For what it's worth though, Loom threads are planned to be fully preemptible.

Sounds like we’re agreeing - nobody _wants_ to write async code cos it’s terrible. You didn’t quite perfect the syntax above but I’m not denying it’s possible - Clojure treats async as a library, not a fundamental language feature, for example. And now with Loom the implementation is even simpler. People want to write synchronous code that can run in parallel without having to do something weird. History will hopefully prove that this is best solved as an implementation detail, not as part of a language’s semantics.
Hear, hear

The worst part of Rust, too, is that async/await is tacked on— and it’s just a bad primitive to start with.

I have many more thoughts on this that I might like to blog about, but it can be improved by having a async runtime of some kind (we don’t call malloc a runtime, but it is— and you need something similar for ergonomic async) — to wit, the de facto pseudo-answer for this in Rust is tokio (which should just be promoted to the stdlib, at this point; the vast majority of async code depends on it’s particularities).

It’s also causes quote-unquote “function coloring problems” left, right, and center — which is also avoidable. Just for kicks, consider a language with “call-async”/“yield”. Tie that in with a runtime and this whole topic becomes much, much, cleaner. Async at the callsite! (This is the blog I’ve been meaning to write)