News for hackers. Stuff that matters.
Re:JavaScript async/await implemented in V8 by tomp on Tuesday May 17, 2016 @04:28AM (#11712040)
Can anyone point to a good explanation why this is preferable to cooperative threads (coroutines)? I.e. the above code could easily be written as

  function main() {
    try {
      const res = fetch('https://api.github.com/orgs/facebook');    // yield here
      const json = res.json();                                      // yield here
      console.log(json);
    } catch (e) {
      // handle error
    }
  }
and the runtime would automatically yield this coroutine and let other coroutines run whenever some call blocks.

I guess the only realy difference would be that I would make `await` (and `async`) implicit, similar to how exceptions are handled implicitly in the above snippet (i.e. we don't annotate functions as `throwing` and we don't use an `attempt` statement (analogous to `await`) when calling `throwing` functions).

Edit: Reading various articles, the best explanation is that since the single-threaded nature of JavaScript makes synchronisity implicit (i.e. all code is run in an implicit transaction), it has to make asynchronisity explicit. The alternative would be to have coroutines/fibres (implicit asynchronisity), but with explicit `atomic` blocks (for synchronisity).

C# doesn't provide any synchronisity guarantees, so I guess the motivations there were different (it's really hard (impossible?) to implement fibres efficiently, and even harder to allow for native code interoperability).

Re:JavaScript async/await implemented in V8 by xg15 on Tuesday May 17, 2016 @07:24AM (#11712654)
There is also the the point of flexibility. Async/await works on promises, however promises themself are just perfectly un-magical JS objects that accept a callback. This results in two effects:

1) Yielding is decoupled from the asynchronous action itself, giving the caller fine-grained control when to yield. For example, with async/await, management of parallel operations is straight-forward:

  var promise = fetch('https://foo.com/');
  // ... do something useful while the fetch runs ...
  var result = yield promise;
Same goes for concurrent fetches:

  var promise1 = fetch('https://foo.com/');
  var promise2 = fetch('https://bar.com/');
  [result1, result2] = yield Promise.all(promise1, promise2 );
2) Promises + async/await allow you to switch back-and-forth very easily between callback-style and coroutine-style APIs, which makes integrating old APIs very easy:

  async function f() {
   var p = fetch('https://foo.com/');
   p = p.then(function(inbetweenResult) {return new Promise(function(resolve) {
    oldapi.onresult = resolve;
    oldapi.process(inbetweenResult);
   })});
   return await p;
  }

  f().then(...) 
... and so on.
Re:JavaScript async/await implemented in V8 by cwmma on Tuesday May 17, 2016 @09:38AM (#11713494)
The explicitness is the reason currently you can assume* that if nobody will ever modify variables unless you explicitly give up control somehow, if you were to have implicit await then that would no longer be the case and any function call could theoretically pause the function and give up control to other functions.

*certain DOM APIs due violate this contract, notably window.open() on firefox pauses everything but setTimeout.

Re:JavaScript async/await implemented in V8 by olau on Tuesday May 17, 2016 @11:51AM (#11714615)
Just to expand a bit upon this: That you can assume a single thread simplifies the code immensely, e.g. when modifying state. It's important to be explicit about when this assumption is broken.
Re:JavaScript async/await implemented in V8 by gpderetta on Tuesday May 17, 2016 @09:45AM (#11713547)
The problem with that is that any mutable escaped variable (i.e. explicitly or implicitly global) can be potentially modified by any function call. On the other hand a non escaped variable cannot be mutated behind your back, yield or no yield. At least, that's the case in a sane language, not sure about JS.
Re:JavaScript async/await implemented in V8 by cwmma on Tuesday May 17, 2016 @09:54AM (#11713611)
escaped/non-escaped variables are not a thing in JS
Re:JavaScript async/await implemented in V8 by gpderetta on Tuesday May 17, 2016 @09:58AM (#11713647)
There are no locals in JS (honest question)? If that the case you have to assume that everything can be mutated everywhere unless for those functions that explicitly and fully document their side effects (and yield would certainly be a side effect).
Re:JavaScript async/await implemented in V8 by cwmma on Tuesday May 17, 2016 @10:46AM (#11714069)
variables declared with the var keyword are functionally scoped in JS so they are local to the function they are declared in and are lexically scoped to the closure of that function. So your local variables you can be fairly confident are not mutated anywhere else.

That being said you can totally have globals and whatnot that can be mutated anywhere (e.g. parameters passed to a function or literal globals installed in the global scope) or things declared at a lower scope that can still be modified by multiple functions.

Hope that clears it up

Re:JavaScript async/await implemented in V8 by amelius on Tuesday May 17, 2016 @05:18AM (#11712201)
Perhaps this is the reason:

Is it possible to have a yield inside a called function (i.e., not the generator function itself)? Last time I checked this was not allowed (?)

Anyway, if so, I would strongly prefer this over a async/await construct, which is less general.

Re:JavaScript async/await implemented in V8 by masklinn on Tuesday May 17, 2016 @07:23AM (#11712644)
> Is it possible to have a yield inside a called function (i.e., not the generator function itself)?

Call a generator function from a generator function? Sure, you just need to transitively yield its content using `yield* [[expr]]` (which delegates part of the iteration to the `expr` generator)

Re:JavaScript async/await implemented in V8 by amelius on Tuesday May 17, 2016 @07:27AM (#11712664)
So what tomp is doing:

    const res = fetch('https://api.github.com/orgs/facebook');    // yield here
actually requires a "yield" in front of the "fetch"? But what if I want the fetch() function to decide whether to yield or not?

Of course, fetch(), could yield a status specifying whether its calling-ancestors should yield, but this can become unwieldy very quickly, and might require an exception mechanism of its own. Better to just let called functions yield.

Re:JavaScript async/await implemented in V8 by masklinn on Tuesday May 17, 2016 @08:11AM (#11712899)
In javascript it would yes (actually a `yield*`, or an `await` in async/await). With native coroutines it wouldn't (the runtime would implicitly yield on IO).

> But what if I want the fetch() function to decide whether to yield or not?

In javascript? The question doesn't really make sense, a function is either sync or async.

Re:JavaScript async/await implemented in V8 by amelius on Tuesday May 17, 2016 @10:08AM (#11713730)
> The question doesn't really make sense, a function is either sync or async.

Well, either fetch() blocks, or not. If it blocks, then it should yield, its caller should yield, etc. If it doesn't block, then it can just run to completion.

Re:JavaScript async/await implemented in V8 by masklinn on Tuesday May 17, 2016 @10:23AM (#11713872)
Don't elide important parts of the quote. In javascript your question doesn't make sense.

> Well, either fetch() blocks, or not.

Javascript functions always block.

> If it blocks, then it should yield, its caller should yield, etc. If it doesn't block, then it can just run to completion.

If a function is async, you must yield[0]. It may not need* that capability (conditionally) and doesn't have to yield at all e.g.

    function*() {
        return 4;
    }
is valid and will not suspend. You must still yield*[0] on it so that it is properly resolved as a generator.

[0] I think that's not an issue for async/await as it's syntactic sugar for then chains, the code itself may be converted to a generator or whatever but it will embed the driver

Re:JavaScript async/await implemented in V8 by a-saleh on Tuesday May 17, 2016 @06:22AM (#11712414)
Is this the problem Python has solved with 'yield from' construct?
Re:JavaScript async/await implemented in V8 by neoeldex on Tuesday May 17, 2016 @08:11AM (#11712901)
Its basically the same thing. But javascript doesn't come with a new eventloop and other construct to use it, since similar functionality is already in js
Re:JavaScript async/await implemented in V8 by totemizer on Tuesday May 17, 2016 @06:49AM (#11712507)
Probably not preferable. Async await works on top of promises...
Re:JavaScript async/await implemented in V8 by turblety on Tuesday May 17, 2016 @04:46AM (#11712083)
It might be something to do with backwards compatibility.
Re:JavaScript async/await implemented in V8 by tomp on Tuesday May 17, 2016 @04:59AM (#11712135)
What do you mean? Edit: I mean, can you give any examples of how old code would be broken by implementing something like this?