I mean the bane of javascript is the whole async programming with callbacks. Instead of solving the specific problem, this solves some problem which I don't see most apps having. Can someone in the know how care to explain?
I mean the bane of javascript is the whole async programming with callbacks. Instead of solving the specific problem, this solves some problem which I don't see most apps having. Can someone in the know how care to explain?
The bane of JS really isn't async programming- it is branching async logic and this is exactly the problem that generators will solve. Moreover, libraries can choose to wrap them into callbacks so they will be backwards compatible.
To get an idea of what this will look like, check out this library I wrote for Luvit (Nodejs for Lua) which relies on callbacks and coroutines to make async code look sync.
yield = await
Also, async/await themselves have a proposal accepted into ES7: https://github.com/lukehoban/ecmascript-asyncawait
For example, var data = await downloadSomething();
function *downloadSomething() { // check somethings
return await http.get('foo.com', function (result) { yield result; });
}The above won't work since the callback to http.get is not a generator.
You cannot make the callback a generator because it's not what a http.get expects. AFAIK, you have to instantiate a generator unlike a normal callback.
Did c# actually require all the code to be changed into generator functions/new syntax to support await/async?
Async/await has identical limitations. You cannot call an async function from a synchronous one. Asynchrony poisons the entire callstack—everything that calls you must also become async.
> Did c# actually require all the code to be changed into generator functions/new syntax to support await/async?
I'm not sure if C# has this limitation, but if not, it's because C# has threads. If you call an async method from a sync one, it can just pause the sync one and run the async one on a different thread. JS can't do that.
I imagine the reason they avoided doing this was to not require browser vendors to make half their browser internals safe for usage in reasonable coroutines ;P. I can also see them having wanted to guarantee that the feature could be implemented using a transpiler rather than requiring it to be a native feature of the browser, and generators being explicitly marked at both the declaration and call sites (or async await with the limitations you mention) have that property by allowing a continuation passing transform to be applied to the generator's code. (Which could be applied to all code, of course, but not native browser code. edit: Well, you could so that as well, but it would violate other assumptions about how the code is supposed to work, and isn't something anyone has infrastructure to accomplish ;P.)
In essence, that's the choice Go made. It's certainly simpler for the programmer. It probably makes optimization trickier, and it probably makes efficient parallelism harder (since real threads are completely abstracted away, the VM needs to understand when to start real threads, and when to use promises).
For a language like javascript, it sounds like these tradeoffs are certainly worth it.
It's a compile-time transform that hoists parts of your function into independently scheduled asynchronous tasks & task callbacks. So it's essentially automatic CPS + promises. That's why functions are tagged as 'async' or not-async in C#; if they are 'async' they produce a promise instead of a value.
On a related note, part of C#'s async/await infrastructure is a scheduling system so that callbacks can be configured to run on a specific thread - i.e. you can kick off async work on the UI thread and the callbacks will run there, instead of on the threadpool thread that completed the work.
Most good JS coders never even have 'callback pyramids'. The pyramid is a symptom of
A) bad modularity and encapsulation in your code and
B) lack of clarity on which tasks depend on one another.
The author ends up with a long 'laundry list' of things that happen to work in a certain order, and needs to ensure they happen in that exact order, using a pyramid.
Having await/async will make node.js programming infinitely better. Lots of programming tasks in server side are really 'step' driven i.e doing a lot of things one by one. Of course, at this point someone will point me to 'async' and 'step' and 'q' modules but that's not the point.
This was the rationale behind Kal (https://github.com/rzimmerman/kal/), which effectively provides "await" (called "wait for") in ES5.
Forget about Dart. :-(