On an aside: what javascript really needed was async/await instead of generators. I have no clue why something as abstract as generators is being pushed.
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 disagree on both fronts. Languages should provide primitive constructs and allow libraries and frameworks to sort out the rest. It is nearly impossible to change a language after the fact, but libraries are free to come and go.
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.
From what I can tell, The generator pattern requires you to make all your functions generators. My understanding is that you can use yield only inside generators.
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?
> My understanding is that you can use yield only inside generators.
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.
This is only true if you are building the implementation of async/await as a compilation hack (maybe a "transpiler", as people now like to say) rather than as a feature of the virtual machine. You don't need "threads" to implement this, you just need the ability to work with multiple stacks and then have use the techniques from coroutines. (Some people call this "green threads", but that's not the kind of "threads" you would refer to when saying C# has threads.)
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.)
To condense what you're saying to its core: you can avoid the need to make callers async if you simply make everything async.
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.
there are third party libraries (bluebird, co, Q, etc) that use generators to yield promises (or lightweight alternatives such as 'thunks'), and then a helper function that handles waiting for those promises/thunks to return and then resuming the generator. annoying that its not baked into ES6, but it means async code can be basically written like sync code (including typical error handling)
Yeah, but only in the most trivial sense. Generators are a very, very poor substitute for proper yield support, just as they were when Python devs used them in Twisted.
your comparison of generator/yield to async/await isn't exactly true... projects like co and koa take the generator/yeild combined with promises/thunks in order to satisfy similar requirements, but they are far from the same.
Please correct me if I'm wrong, but I think with generators, the caller has to keep calling next on it, which you don't have to with C# style async-await.
So 'async' functions return a generator? If a library uses async-await, the library users have to call next on the generator? I assumed the language handled resuming the generator, so the users didn't have to.
What's the bane of JS? Callbacks? That's probably because you were trained on languages without heavy use of asynchronous concepts. JS is my first language, and I have never had any sort of issue with callbacks.
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.
I agree with your points but I was talking in the context of node.js.
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.
Good point. No reason not to have tools in the toolbox for when you need them. You might be interested in https://github.com/Raynos/continuable for dealing with async, it is an extremely simple library that allows you to build up async ops step by step. When you call the resulting function, it runs all the steps in the order you defined them.
I strongly agree. What would help most JS programmers (especially in node) would be to leverage the great asynchronous features in JavaScript and eliminate the nested function pyramid of doom. Callbacks and nested functions work great until you have conditionals or want to use try/catch blocks in a reasonable way. Promises are a viable solution but I've never really been a fan (it just feels weird).
The author shows a micro benchmark in which the state of the generator is a single variable and discuss the history of generators from the first tier (interpreter code) to the second tier (using the Jit). Perhaps some more complete examples with should be analyzed since the case discussed here seems to be the simplest and so the 22 times faster perhaps doesn't hold except in very simple cases.
Of course generators are completely unusable until other browsers start to support them.
That is, unless you use a compiler to convert your generator code into more mundane javascript [1]. It would be nice to see these "emulated generators" in the comparison too.
That's not true. If you look at http://kangax.github.io/compat-table/es6/ you'll see IE11 preview (their "canary") has more green than any other browser including Chrome or Firefox. Yes, even more than Firefox nightly or Chrome canary.
while that's sort of true, the big distinction is that the features in their "canary" aren't going to hit "stable" for another year or so, which is a lot of iterations of Firefox and Chrome in the meantime.
However, it is fantastic to see where they're headed with IE12.
I only partially agree here... in this generation of apps, you're going to wind up using traceur or es6ify for the most part, unless you're building a bundled app that targets a browser shell (cordova, node-webkit, etc) that can make the option available.
I'm actually slightly annoyed that I have to run the dev version of node and the --harmony flag to get the new JS options server-side... but seeing what co/koa do with generators is really nice... I'm stuck transforming my client-side scripts for a while... it will be nice when I don't need to browserify/es6ify anymore.
Nowadays, every time!, I am hearing some news about Firefox getting better, I feel that's a lie. I feel Firefox is actually getting worse and worse, from disappointment to disappointment. Either when it's a new feature or new UI modifications (I loved to have a separation between the URL and the Google search != Chrome), or new web services (Mozilla "Labs"?), or new dev. tool (Firefox inspector is at best full of small bugs and seems to be an ugly copy and paste from Firebug). Hopefully the Mozilla CEO being fired will make things better but I feel now being mediocre it's new culture trend @ Firefox.
I'm not sure I completely agree... Honestly, there are many developers each working on stuff they are either required to do, or want to do. The only time I find the unibar in chrome annoying is when I'm searching for something specific to google... and effectively have to type google twice (first time sets the search site to google).
As for the developer tools, I do wish it was closer to either the chrome dev tools or firebug myself, it looks too much like the IE10+ tools, which I find annoying. But that's a matter of preference.
This is a matter of raw performance, not a subjective UI.. FF has made a lot of effort into improving JS at its' core... Chrome has worked to expanding the DOM in interesting ways. IE has taken a pragmatic approach to refining what comes from both, though having their own issues. The browser ecosystem today is so much better than it has ever really been, and I couldn't be happier about it.
You can relatively easily create your own skin against a Firefox base. AFAIK it's still all XUL wrapped around a web view, and pretty easy to get into, admittedly last time I tried was 6+ years ago. Chrome is still my favorite browser, but I do appreciate what the others are doing... the best ideas do get copied, and it works.
I feel exactly the opposite, I've downloaded the Developer Edition which they released a few days ago and I've never seen a browser so fast, it feels much faster than chrome on my machine, I can't wait to have all the beta improvements merged into the standard version !
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?