ECMAScript.next: TC39’s November 2012 meeting

[2013-01-13] esnext, tc39, dev, javascript
(Ad, please don’t block)
From November 27-29, 2012, the Ecma Technical Committee 39 (TC39, [1]) had another meeting, where decisions were made about ECMAScript.next (the code name for ECMAScript 6 [1]). This blog post summarizes and explains the highlights. It is based on Rick Waldrons excellent notes that he put up on GitHub. There is also a list of all 2ality posts on TC39 meetings.

November 27

  • TC39 approved the final draft of the Internationalization API (ECMA-402). Since then, on December 12, the Ecma General Assembly unanimously approved ECMA-402, making it a standard. The API exists separately from ECMAScript and can be used under ECMAScript 5 or later. Plans for version 2.0 are currently being made. High-priority functionality includes case conversion and message formatting that can handle things such as gender and grammatical number. Alex Slexton has experience with message formatting [2] and will be consulted.
  • String.prototype.normalize(): Sometimes several Unicode code points represent the same character. Normalization ensures that for each such character, the same character is used everywhere. That helps with comparing strings and with searching for text.
  • Generator functions [3] will get their own prototype GeneratorFunction, a sub-prototype of Function. That object is not global, though, it must be imported from a module. The following three expressions all test whether f is a generator function.
        f instanceof GeneratorFunction
        f.__proto__ === GeneratorFunction.prototype
        f.__proto__ === (function *() {}).__proto__
    

November 28

Symbols

Among other things, symbols are used for private properties in ECMAScript 6 [4]. A proposal for adding special syntactic support for them has been rejected, you’ll have to create them “manually”:
    let _id = new PrivateSymbol();
    let _log = new PrivateSymbol();
However, computed property keys have been revived and will be part of ECMAScript.next. Currently we only have static property keys. In ECMAScript.next, you’ll also be able to write an expression in square brackets and its result will be used as the key. For example:
    let logger = {
        [_id]: "ID2543",
        [_log](message) {
            console.log(this[_id]+": "+message);
        }
    };
You can only access the two properties above if you know the values in _id and _log. They can’t be listed via the usual means (Object.getOwnPropertyNames(), for-in, etc.), either. Computed keys also work in ECMAScript 6 classes [5]:
    class LoggerFactory {
        constructor(id) {
            this[_id] = id;
        }
        [_log](message) {
            console.log(this[_id]+": "+message);
        }
    }
The advantage of this approach is that it gives you a lot of freedom, because you can explicitly control who has access to a symbol. The disadvantage is that every private identifier has to be declared in advance, leading to redundancy. TC39 does not rule out adding syntax after ECMAScript 6 to reduce some of that work.

Modules

The design of modules is work in progress. The following snippets demonstrate current ideas.

Defining a nested module:

    module "foo" {
        module "bar" {
            // ...
        }
    }
    // Equivalent:
    module "foo/bar" {
        // ...
    }
Importing a nested module:
    import "foo/bar" as m;

November 29

Chaining calls to collections

The following methods will return this:
  • Map.prototype.set
  • WeakMap.prototype.set
  • Set.prototype.add
That allows one to chain them. For example:
    let s = new Set();
    s.add('foo').add('bar');
Or even:
    let s = new Set().add('foo').add('bar');

Iterating over objects

ECMAScript 6 will have an iteration protocol [3]. An object adheres to that protocol by providing a method whose key is the well-known symbol @@iterator. The method returns an iterator over the “elements” of the object. An object that implements the iteration protocol is called iterable. Arrays and the Array-like arguments object will be iterable. Iteration operations use the iteration protocol as follows:
  • Array.from converts iterable and Array-like objects to arrays. If the iteration protocol is supported, it uses it. Otherwise, the object is considered Array-like and converted accordingly.
  • for-of loop [3]: only supports iteration protocol.
  • Spread (...) operator: only supports iteration protocol. This operator allows one to insert the elements of an array into a function call or an array literal. Examples:
        myFunc(a, b, ...myArray, c)
        [a, b, ...myArray, c]
    
    Among other things, spread can often be used instead of apply().

Collection APIs

The collection types Array, Map, WeakMap and Set will have the following three methods that return iterables (not iterators!):
  • keys(): returns an iterable of the keys of the collection.
  • values(): returns an iterable of the values of the collection.
  • entries(): returns an iterable of two-element [key,value] arrays.
There will be functions (importable from a module) that perform the same operation for objects. That is, objects will not be iterable. The rationale for that is to keep iterating of the content of an object such as a collection separate from iterating over the properties of an object.

let declarations in non-strict code

let is only a keyword in strict mode (ECMA-262, Sect. 7.6.1.2). Thus, the following code is legal in non-strict mode.
    var let;
    let[x] = 5;
The second line could be mistaken for a let declaration, because ECMAScript.next will have destructuring assignment. For example:
    [x, y] = [y, x];
    let [a, b] = computePair();
    let [c] = computeSingleElementArray();
The following rules will be used for parsing let:
let at the beginning of a statement is a let declaration, but it must be followed by either an identifier, an opening square brace "[" or an opening curly brace "{".
This rule does not prevent the above mentioned problem in old code, but TC39 will try and inform people about it, so that hopefully nothing important breaks once this feature appears in browsers. However, the rule does prevent all other problems with using let as a variable name.

Array comprehensions and generator comprehensions: two new clauses

As explained in [6], there can be four kinds of clauses in comprehensions: for, if, let, const. The last two are new.

References

  1. ECMAScript: ES.next versus ES 6 versus ES Harmony [also explains what TC39 is]
  2. Jed – a JavaScript internationalization toolkit
  3. ECMAScript.next: for-of, iterators, generators
  4. Private data for objects in JavaScript
  5. ECMAScript.next: classes
  6. ECMAScript.next: array comprehensions and generator comprehensions