ES6 doesn't need opt-in

Oliver Hunt oliver at apple.com
Sat Dec 31 18:08:14 PST 2011


On Dec 31, 2011, at 5:46 PM, David Herman wrote:

> Happy new year, everyone. I've got some good news.
> 
> There's been grumbling lately about the ES6 version opt-in [1]. The detractors are not right about everything, but it's true that both the MIME type opt-in:
> 
>    <script type="application/ecmascript;version=6">
>        ...
>    </script>
> 
> and the pragma opt-in:
> 
>    use version 6;
> 
> are painful -- ugly, verbose, and a permanent tax for opting to use the new semantics.
> 
> We can do better, and the way we can do it is with modules. We can introduce module syntax in a backwards-compatible way, and use them as the implicit opt-in for any new semantics [2].
> 
> And the benefit we get is **just one JavaScript**.
> 
> # Backwards-compatible syntax
> 
> Both `use` and `module` can be contextual keywords, with a restricted production that disallows a newline after the keyword. To avoid ambiguity with contextual infix operators like `is` and `isnt` [3], such as:
> 
>    module is {}
> 
> we can resolve in favor of the declaration form in statement context, and in any other expression contexts `module` is just an ordinary identifier.
> 
> This is totally backwards-compatible: all the new forms would have been parse errors in ES5:
> 
>    module foo { }
>    module bar {
>    }
>    module {
>    }
> 
> and in all cases that ASI accepts in ES5, it continues to parse the same, i.e., not as a module:
> 
>    module // semicolon inserted
>    foo    // semicolon inserted
> 
> # Modules as the opt-in for new semantics
> 
> Any ES6 feature that breaks web-compatibility can be made available only within module code. For example, if `let` as a keyword breaks the web, then in global code we treat it as an identifier, but we treat it as a keyword once you're inside a module. Similarly, the proper but backwards-incompatible scoping semantics for block-local functions would only be enabled within module code.
> 
> We could do the same for `yield`, but since it's only meaningful within function*, we should allow generator functions outside of modules as well. I'm not sure whether we can/should reserve `yield` as a keyword in global code.
> 
> Each new feature can be considered independently. Anything that is only allowed within modules becomes a carrot to lead programmers to the improved semantics, but whenever we can compatibly make something available to global code, we should do so. No point needlessly depriving programmers of ES6 goodies such as destructuring or spread/rest.

I'm willing to have a shot at making JSC treat a bunch of the current "reserved only in strict mode" keywords be reserved globally and see what breaks in the nightlies.  I think yield is a special case in that it only applies inside generators anyway, so making it "contextual" in generators seems obvious.

> 
> # What about eliminating the window from the scope chain?
> 
> Short answer: giving up.

I think we can drop the global object from the scope chain in ES.  In the context of the browser we need to come up with a way to trigger it.
> 
> # Summing up
> 
> We can make ES6 100% backwards-compatible, using modules to opt in to backwards-incompatible changes. It replaces the notion of a new language "mode" with the simple syntactic characteristic of whether the code is in a module. And you can now mix old code and new code freely, even within the same <script> tag or source file.

Someone brought up the typeof semantic change as concern :-/



More information about the es-discuss mailing list