ES6 doesn't need opt-in

Brendan Eich brendan at mozilla.com
Wed Jan 4 12:16:42 PST 2012


On Jan 3, 2012, at 11:29 PM, Mark S. Miller wrote:

> On Tue, Jan 3, 2012 at 10:18 PM, Brendan Eich <brendan at mozilla.com> wrote:
> On Jan 3, 2012, at 9:52 PM, Mark S. Miller wrote:
> 
> > A good example. Since the class proposal uses  "private, public, static", by these principles, it would only be recognized in strict mode. If it appears in non-strict code, it would be a SyntaxError.
> 
> That's a choice. I'm asking why it's the best one. Just because class syntax might involve new reserved identifiers doesn't require strict mode. The introductory keyword is class and the new keywords are all in the braced body.
> 
> The idea is that the always-reserved 'class' keyword is opt-in enough -- no need for a "use strict"; string litearl (ignored by old browsers anyway!).
> 
> "opt-in enough", interesting. I'm not sure if this is what you meant, but it suggests a very attractive option I hadn't considered: treat "class", like "module", as yet another way to opt-in to strict mode. All code recursively inside a class would be strict.

Yes, that's what I meant.

Harmony > ES5-strict <!> ES5 (> means supserset, <!> means neither super- nor subset).

Any new Harmony syntax that presents no backward incompatibility *and* has a body opts the body into the new edition, a superset of ES5-strict.


> For class, you're right. I really like the idea of having it be another way to opt-in to strict mode. What other constructs might join "class" and "module" as new strict-mode opt-ins?

As Dave mentioned, generators:

  function* Fibonacci() {
    let [a, b] = [0, 1];
    for (;;) {
      yield a;
      [a, b] = [b, a+b];
    }
  }


> 
> > Want to use "let" scoping outside a module? Again, just say "use strict";.
> 
> The string literal directive is meaningless in old browsers, and the other new syntax than let is guaranteed to fail with a syntax error in old engines, so what's the benefit of requiring the extra "use strinct"; again?
> 
> Huh? In ES5, the following code is legal:
> 
>     var let = 88;
> 
> The following code is not:
> 
>     function foo() { "use strict"; var let = 88; }

Consider instead these examples:

  var let = 88;
  function foo() { "use strict"; let bar = 99; }

My point was pre-ES5 implementations don't respect "use strict", so the first line works while the second line fails with an early error due to unrecognized 'let'. As you note, ES5 implementations support the first and fail on the second with a different early error.

Now, if ES6 implementations extend "use strict" to enable let, then suddenly both work.

Therefore if authors face ES5 and ES6 implementations in the field, saying "use strict" is not enough to reliably use 'let'. True, ES5 implementations will fail with an early error -- just as they would on class or module declarations. But they'd fail on most 'let' declarations anyway, so why should "use strict" be required?

This is the question: if 'let' can be used reliably only in ES6 implementations and it fails fast in pre-ES6 implementations, why insist on, or educate users to add, "use strict" -- especially when that is not meaningful to pre-ES5 browsers, and the only difference between pre-ES5 and ES5 browsers is what kind of early error (perhaps just the message detail) is thrown?


> I don't want to twist the grammar to turn "let" into a context sensitive reserved word so that somehow
> 
>     "var let = 88;" and use of let-scoping can co-exist in the same mode. This seems like too high a price to pay simply to avoid any of the strict mode opt ins.

Agreed, that is a bridge too far and we've said so before. Gavin B. was asking again about it and I replied citing destructuring (let [x] = y; after another terminated statement) as one ambiguous case.


> Any code under active maintenance should opt-in to strict somehow anyway.

You think so but developers are not doing it. Some have tried and been burned by concatenation without testing in ES5 implementations. Others don't like the performance effects (real but not necessarily biting them). "use strict" is not catching on, sorry to relate, and this is why I do not think we should yoke 'let' to it.

If we don't need to predicate 'let' on "use strict" to avoid backward incompatibility (other than in details of early error thrown), then we should not. The destructuring ambiguity remains, but perhaps there is a solution. Still thinking about this...


> Non-strict mode is only for legacy that needs to keep working without any further human attention -- most of the web. This code already doesn't use let scoping, so what's the issue?

There are two issues:

1. Needless "use strict" when new syntax (mostly or completely) is necessary and sufficient opt-in by itself. We agree this is the case for class and module -- also (I hope) for function*.

2. Lack of "use strict" adoption means coupling to it too much raises risk of ES6 non-adoption.


> Again, the criteria I care about is "practically backwards compatible". If it works to simply make "let" an unconditional keyword, then we should. On this one, I'm skeptical. It is a short three letter english word. If there are not many uses of it as a variable name, I would be very surprised.

Could be, I'm not sure how popular 'let' is in the field. Finding true positives would be conclusive, esp. in number.


> On typeof, I am more than skeptical. I think this one is likely impossible without a third mode. But if the data says otherwise, we should go with the data.

This one needs some smart automated web code analysis. I'm stirring that pot.


> But the "previously-illegal token sequence" approach complicates the grammar and readability in ways that are not worth it, just to avoid any of the means of opting in to strict, which all non-legacy code should do anyway. For modules, we'd be taking the "previously-illegal token sequence" approach in order to avoid introducing a third mode, which is so valuable that the grammar and readability complexities are worth it.

And for classes. And for generators? If yes for generators, then why not for comprehensions, rest/spread, destructuring (separate from the 'let' issue), for/of, and other new forms? 

/be

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20120104/43c5295d/attachment.html>


More information about the es-discuss mailing list