David Herman on ECMAScript.next

[2011-02-24] esnext, dev, javascript
(Ad, please don’t block)
David Herman has posted a video of his talk on what he calls ECMAScript.next, the next version of JavaScript. Others call it “JavaScript Harmony”. It nicely complements my recent post on Brendan Eich’s ideas for Harmony [1], with a little overlap, but not much.

Roadmap for ECMAScript.next:

  • Spring 2011: proposal freeze (no more proposals allowed)
  • 2013 (roughly): spec finished, parts will be in browsers before that.
  • opt-in via MIME type in script tag: <script type="application/javascript;version=next"> (where “next” is a placeholder for something that has still to be determined)
Broad themes:
  • Fixes: removing quirks
  • Expressiveness: support better, more concise idioms
  • Power: doing what couldn’t previously be done


  • Eliminate the arguments variable:
        function foo(x, y, ...rest) {
  • Extending typeof: "null" for null (currently "object")
  • Don’t auto-create global variables (already in strict mode [2])
  • Block-scoping, not function-scoping [3], via let (“let is the new var”)


Sharp functions. [As an aside, these could also be called “pounders” from “pound sign” or “hash functions” (but: already used in the context of hashing).]
  • Old: var sizes = elts.map(function(elt) { return elt.size() });
  • New: var sizes = elts.map(#(elt) { elt.size() }) // implicit return
  • Non-methods don’t have implicit this argument, any more. Must declare explicitly that you expect this in sharp functions.
Module system.
    module SpriteCore {
        export function Canvas(...) {...}
Or separate file:
    export function Canvas(...) {...}
Current way of loading a module: callback works with module.
    require("lib/SpriteCore.js", function(SpriteCore) {
        require("lib/jQuery.js", function($) {
Future way of loading a module: client determines module name, which avoids conflicts and makes module names shorter.
    module SpriteCore = "lib/SpriteCore.js";
    module $ = "lib/jQuery.js";
    import SpriteCore.*; // unqualified import
    function Element({width: w, height: h, color: c}) { ... }
    var [key, val] = find(...);
Generators (inspired by Python). A generator-based library helps with callback-heavy code. Given the following code.
    XHR.load("x.txt", function(x) {
        XHR.load("y.txt", function(y) {
            XHR.load("z.txt", function(z) {
                // work with x,y,z
            }, onError);
        }, onError);
    }, onError);
This can be simplified to:
    let task = new Task(function() {
        try {
            let x = yield XHR.loadAsync(this, "x.txt");
            let y = yield XHR.loadAsync(this, "y.txt");
            let z = yield XHR.loadAsync(this, "z.txt");
        } catch(e) {
    task.start(); // start cooperative thread


Map and sets for arbitrary values (not just strings, as via objects). Also: weak maps (does not prevent values from being garbage collected).
    let map = new Map();
    map.set(obj, 42);
    map.get(obj) === 42

    let set = new Set();
    set.has(obj) === true
Various other things:
  • Proper tail calls. Use case: If you tail-call a function, it can determine what to do next, via another tail call. Not needed often, but useful.
  • Binary data via structured types: can be read from a binary stream, complement typed arrays.
        let Point2D = new StructType({ x: uint32, y: uint32 });
        let pt = new Point2D({ x: 0, y: 0 });
  • Proxies: create an object with a handler that implements all ways of accessing the object (reading a property, writing a property, invoking a method, etc.). Use cases: logging, remoting.
  • Module loaders: implement custom semantics for modules (e.g. CoffeeScript modules, Python modules, static checking of JavaScript, etc.).

Related posts

  1. Brendan Eich’s dream for the next version of JavaScript
  2. JavaScript’s strict mode: a summary
  3. JavaScript variable scoping and its pitfalls