es6 generator and array comprehensions in spidermonkey

7 March 2014 9:11 PM (es6 | igalia | spidermonkey | firefox | bloomberg | compilers | javascript | generators)

Good news, everyone: ES6 generator and array comprehensions just landed in SpiderMonkey!

Let's take a quick look at what comprehensions are, then talk about what just landed in SpiderMonkey and when you'll see it in a Firefox release. Thanks to Bloomberg for sponsoring this work.

comprendes, mendes

Comprehensions are syntactic sugar for iteration. Unlike for-of, which processes its body for side effects, an array comprehension processes its body for its values, collecting them into a new array. Like this:

// Before (by hand)
var foo = (function(){
             var result = [];
             for (var x of y)
             return result;

// Before (assuming y has a map() method)
var foo = { return x*x });

// After
var foo = [for (x of y) x*x];

As you can see, array comprehensions are quite handy. They're expressions, not statements, and so their result can be passed directly to whatever code needs it. This can make your program more clear, because you aren't forced to give names to intermediate values, like result. At the same time, they work on any iterable, so you can use them on more kinds of data than just arrays. Because array comprehensions don't make a new closure, you can access arguments and this and even yield from within the comprehension tail.

Generator comprehensions are also nifty, but for a different reason. Let's look at an example first:

// Before
var bar = (function*(){ for (var x of y) yield x })();

// After
var bar = (for (x of y) x);

As you can see the syntactic win here isn't that much, compared to just writing out the function* and invoking it. The real advantage of generator comprehensions is their similarity to array comprehensions, and that often you can replace an array comprehension by a generator comprehension. That way you never need to build the complete list of values in memory -- you get laziness for free, just by swapping out those square brackets for the comforting warmth of parentheses.

Both kinds of comprehension can contain multiple levels of iteration, with embedded conditionals as you like. You can do [for (x of y) for (z of x) if (z % 2) z + 1] and all kinds of related niftiness. Comprehensions are almost always more concise than map and filter, with the added advantage that they are usually more efficient.

what happened

SpiderMonkey has had comprehensions for a while now, but only as a non-standard language extension you have to opt into. Now that comprehensions are in the draft ES6 specification, we can expose them to the web as a whole, by default.

Of course, the comprehensions that ES6 specified aren't quite the same as the ones that were in SM. The obvious difference is that SM's legacy comprehensions were written the other way around: [x for (x of y)] instead of the new [for (x of y) x]. There were also a number of other minor differences, which I'll list here for posterity:

  • ES6 comprehensions create one scope per "for" node -- not one for the comprehension as a whole.

  • ES6 comprehensions can have multiple "if" components, which may be followed by other "for" or "if" components.

  • ES6 comprehensions should make a fresh binding on each iteration of a "for", although Firefox currently doesn't do this (bug 449811). Incidentally, for-of in Firefox has this same problem.

  • ES6 comprehensions only do for-of iteration, not for-in iteration.

  • ES6 generator comprehensions always need parentheses around them. (The parentheses were optional in some cases for SM's old generator comprehensions.

  • ES6 generator comprehensions are ES6 generators (returning {value, done} objects), not legacy generators (StopIteration).

I should note in particular that the harmony wiki is out of date, as the feature has moved into the spec proper: array comprehensions, generator comprehensions.

For another fine article on ES6 generators, check out Ariya Hidayat's piece on comprehensions from about a year ago.

So, ES6 comprehensions just landed in SpiderMonkey today, which means it should be part of Firefox 30, which should reach "beta" in April and become a stable release in June. You can try it out tomorrow if you use a nightly build, provided it doesn't cause some crazy breakage tonight. As of this writing, Firefox will be the first browser to ship ES6 array and generator comprehensions.


I had a Monday of despair: hacking at random on something that didn't solve my problem. But I had a Tuesday morning of pleasure, when I realized that my Monday's flounderings could be cooked into a delicious mid-week bisque; the hack was obvious and small and would benefit the web as a whole. (Wednesday was for polish and Thursday on another bug, and Friday on a wild parser-to-OSR-to-assembly-and-back nailbiter; but in the end all is swell.)

Thanks again to Bloomberg for this opportunity to build out the web platform, and to Mozilla for their quality browser wares (and even better community of hackers).

This has been an Igalia joint. Until next time!

31 responses

  1. Arne Babenhauserheide says:

    The generators are actually nice to read - I did not expect that.

    It looks like Javascript is actually growing up to become a somewhat readable language. Thanks for your work on this!

  2. Brendan Eich says:

    Hi Andy, thanks for all the great work.

    Quick note to say that the "legacy" in SpiderMonkey was all proposed for ES4, so standards track, back in the day. It was in turn based on Python 2.5 (but we avoided GeneratorExit).

    Lots of water under the bridge, but I do not believe we would have this stuff in ES6 without a bunch of us old-timers carrying water in those days.

    Maybe via some other path? Who knows. What's certain is that you did the essential ES6 implementation work, so thanks again!


  3. Brendan Eich says:

    Forgot to credit Dave Herman for turning the Pythonic RTL

    x for x in y

    around to read LTR:

    for (x of y) x

    in ES6. Good change!


  4. tomás zerolo says:

    Hi, Andy

    thanks for your blog. Here's one tentative nitpick in return. Shouldn't

    // Before
    var bar = (function*(){ for (var x of y) yield y })();
    // After
    var bar = (for (x of y) y);

    rather be

    ... yield x ...


    As someone not much accustomed to Javascript syntax, this tripped me up at first.

  5. Brandon says:

    Thanks, Andy: "comforting warmth of parenthesis" is now my phrase for the week. I enjoyed a hearty chuckle over that -- good-naturedly, I assure you.

  6. wingo says:

    Thanks for the note, tomás; fixed.

  7. says:

    I enjoyed a hearty chuckle over that -- good-naturedly, I assure you.

  8. says:

    If you like to play online game then this site for you because here freecell game. Freecell game is best soliatire game. You can play single. This is brain game

  9. text twist online says:

    We are really proud of our sussess.we do not plan on stopping this amazing tool any time in the near futurewe are really proud of our sussess.we do not plan on stopping this amazing tool any time in the near future.

  10. How to register a Limited company says:

    Registering a private limited company should not be an issue nowadays as more and more less strict rules are now in the market. Looking for registering a company? Try UNilex.

  11. root explorer apk says:

    root your android device root explorer pro apk and speed up your device

  12. Jack says:

    Thank you for sharing this article - really needed the help

  13. Academic Writing Help says:

    Thankful for sharing this wonderful information! You should post more points of view with respect to different subjects in addition.

  14. Nick says:

    Great content here, thank you very much for sharing

  15. Must See Famous Statues says:

    Beautifully written👏👏i appreciate the hardwork u put in research and finding out the facts..Great job best wishes♥️♥️

  16. says:

    Thanks for this informative post!

  17. Click here says:

    Thank you for sharing this unbelievable post

  18. helix jump says:

    This is a perfect example of the district attorney in need of

  19. says:

    Nice work! Thanks for sharing this post.

  20. says:

    Is this still up till today?

  21. check us out says:

    Glad that these two landed in SpiderMonkey! Good news indeed!

  22. Check our site says:

    Any update on this?

  23. Visit us says:

    Nice post! I keep coming back here for another article. Thank you!

  24. event planner Orlando says:

    I should admit the entire article has been very enlightening and very well written.

  25. says:

    Any update on this generator?

  26. estratégia para ganhar na lotofácil says:

    I should admit the entire article has been very enlightening and very well written.

  27. says:

    Thanks for this detailed array comprehension.

  28. Private Limited Company Registration says:

    Private limited organization enlistment requires some lawful advances and attentive procedures. To finish the procedure of online organization development, you have to think about what is a private constrained organization, how to frame private restricted organization, required archives for an organization arrangement, advantages of private constrained organization arrangement, and so on.

  29. mapquest directions says:

    The article appears as an extremely attractive topic to explain. Your post is extremely helpful to me. Thanks for your great post. I am especially happy to take a look at your post.

  30. Assignment Writing says:

    I had a terrible Monday: going soft cannot solve my problem. But I had a nice Tuesday morning, realizing I could have fun on a Wednesday night on Monday. Advertiser behavior is small and small, which benefits all networks.

  31. sexsaarland says:

    Really appreciate this dedication and time spent for sharing great info, thanks

Leave a Reply