Hacker News new | ask | show | jobs
by Arkadir 4436 days ago
The main reason why writing concurrent code in JavaScript is not completely insane (just moderately so) is because of the single-threaded sequential execution model (also known as cooperative threading).

Asynchronous effects need to remain explicit.

Consider a simple example:

    function binary(stack,combine) {
      var a = stack.pop();
      var b = stack.pop();
      stack.push(combine(a,b));
    }
In today's JavaScript, this code executes as an atomic sequence. It turns [..,a,b] into [..,combine(a,b)] and there is no way for another piece of code to step on this function's toes and break this invariant.

What if "combine()" suddenly became asynchronous ? Either because its operation itself is asynchronous, or the evaluation of "a" or "b" involved an asynchronous operation. This would cause the call to "binary()" to pause in the middle of the function, which would give time to another part of your code to call "binary()" in turn. And now [a,b,c,d] has turned into [a + b, c + d] instead of [a, b + c + d], and you'll have a jolly good old time debugging tht.

Make asynchronous context switches implicit and you start needing locking primitives. Everywhere, including third party libraries that "used to work". Because every single line of code(except plain assignment) could be a ticking async-bomb that will pause the current function and let other functions wreak havoc on your invariants.

Scary.

Callbacks are ugly, and promises are hardly better, but asynchronous operations NEED to stay explicit. And explicit asynchronous operations are contagious. That's just what they are.

Just make the syntax less right-pyramidal: C#'s async/await syntax is a good candidate, and 'await' is a good way to mark a possible context switch.