migrating `let' and `const'
On Nov 15, 2011, at 7:17 AM, Andy Wingo wrote:
Hello,
Do I have it right that the intention with
let' and
const' is to allow them in strict mode?SpiderMonkey appears to allow them, as does V8 with --harmony, but V8 without --harmony and JSC both abort on `const' in strict mode.
This is a gray area. To quote Waldemar from
"It's a judgment call, and I'd take these on a case-by-case basis. For const and let, I see little harm in browsers allowing them now in strict mode with the purely non-hoisting (C++-like) scoping rules, particularly if they complained when you accidentally declared a variable twice directly in the same block."
In order to clear the decks, some engines ban let and const in strict mode. Others (at least SpiderMonkey) allow them because (a) the engine in question supported 'let' with nearly the Harmony semantics; (b) users generally use them in a future-friendly way (no use before initialization, pretend-block-scope for const).
This doesn't matter a whole lot yet on the web, since strict mode is not being adopted aggressively, and where it has been adopted, interoperation constraints mean JS hackers have not used let at all, and (AFAIK) they've not used const either. No 'let' support apart from Firefox, and 'const' isn't in IE (and in Opera it's a 'var' synonym).
For Firefox, or really SpiderMonkey, we have had a 'let' implementation dating to the ES4 proposals era, and it's "close" but of course imperfect. We have many XUL apps and add-ons using 'let' in JS. We would like them to "use strict". So we made the call the other way from V8 and JSC.
Likewise, none of the major engines abort on
const' in non-strict mode. In non-strict mode in browsers, which semantics should
const' have? The old one, with hoisting?
There is no well-specified "old one" -- no 'const' in ECMA-262 yet. The SpiderMonkey implementation dates back to before my hair was gray. It's goofy (have you played with it? var scope, use-before-init ok, you can re-init if in a loop) but with some discipline, programmers can use it carefully, per the Crockford rules for var (manually hoisted, no use before init).
SpiderMonkey maintainers will take the heat of changing 'let' semantics shortly, and making 'const' truly block scoped. The temporal dead zone (no use before initialization) should not break much code. We'll find out how bad a mess we've made, but again it's confined to Mozilla-only apps and add-ons. I'll report to the list on how it's going as this happens.
On Tue, 2011-11-15 at 07:41 -0800, Brendan Eich wrote:
To quote Waldemar from
"It's a judgment call, and I'd take these on a case-by-case basis. For const and let, I see little harm in browsers allowing them now in strict mode with the purely non-hoisting (C++-like) scoping rules, particularly if they complained when you accidentally declared a variable twice directly in the same block."
This makes sense. Thanks for the note.
Related wiki page: conventions:no_non_standard_strict_decls
Andy
On 11/15/2011 07:17 AM, Andy Wingo wrote:
SpiderMonkey appears to allow them, as does V8 with --harmony, but V8 without --harmony and JSC both abort on `const' in strict mode.
If you opt into a version supporting 'let', you get 'let' functionality. If you don't, 'let' is a strict reserved keyword, so use of it is a syntax error. Thus the name is reserved for future use in code that hasn't made an effort to use 'let' functionality; but if it has indicated it wants to use 'let', that use will keep working. (Although how it works might change at the margins after standardization, as Brendan notes. But relatively minor changes in semantics are much easier to do than wholesale disabling.)
Likewise, none of the major engines abort on `const' in non-strict mode.
'const' is just old, far older than 'let', and has never been guarded behind a version check. Other engines probably have mostly JS on the web to target, but SpiderMonkey has Firefox code, extension code, and so on to deal with as well. It didn't seem practical to disable it given all those other users, some of whom definitely do want to use 'const' in strict mode code. And its semantics now are "close enough", as Brendan notes, if you're just using it the natural way with straight-line, run-once-per-activation code. So it works unconditionally in SpiderMonkey. (It's perhaps worth noting you can compile SpiderMonkey without 'const' support at all, although that frob's likely under-tested.)
Please excuse my ignorance, but:
On Tue, 2011-11-15 at 07:41 -0800, Brendan Eich wrote:
To quote Waldemar from
"It's a judgment call, and I'd take these on a case-by-case basis. For const and let, I see little harm in browsers allowing them now in strict mode with the purely non-hoisting (C++-like) scoping rules, particularly if they complained when you accidentally declared a variable twice directly in the same block."
So the current idea is that ES.next has different syntax and semantics, and so in general the strategy would be to offer <script type="harmony">
and otherwise some form of "transpilation".
But you are also proposing to move some ES.next features into the existing ES5.1 strict mode already provided by implementations? This would not be necessary if you relied on "transpilation" when targetting older hosts.
Don't get me wrong, I think that adding block-scoped let' and
const'
to strict mode is the right thing, but the big migration picture is
still a little unclear to me. There seems to be some subset of ES.next
that will be implemented in ES5.1 strict-mode browsers, and some other
subset that will rely on versioning.
Andy
I can explain what V8 is doing/planning to do:
The classic behaviour for const is fairly similar to the one from Mozilla, the inventors of const. The implementation is fairly complicated, involving a magic sentinel that enables the implementation to distinguish between a const variable that has not been initialized and one that has been initialized to undefined. Using const disables optimization except in some very simple cases. const declarations are hoisted to function level. This is unfortunately not the same as Safari, which just implements it as a synonym for var.
In <script type=harmony> mode we plan to support the new non-hoisted semantics.
In order to prevent a silent change of semantics caused by an update of Chromium we don't plan to change the hoisting semantics in classic mode. It is possible that we might make a change to align with Safari's implementation which is slightly less risky (and a nice simplification).
In order to prevent a silent change of semantics caused by addition of 'use strict' we don't want to disable hoisting on strict mode. Instead we ban const in strict mode. The reasoning is:
In order to prevent a silent change of semantics caused by addition of <script type=harmony> we make const a syntax error in strict mode
code. That way, when people add <script type=harmony> (presumably
instead of 'use strict') there won't be any const keywords left in their code.
2011/11/16 Andy Wingo <wingo at igalia.com>:
On Nov 16, 2011, at 3:05 AM, Andy Wingo wrote:
Hi again,
Please excuse my ignorance, but:
No problem, we did not talk about how opt-in works.
On Tue, 2011-11-15 at 07:41 -0800, Brendan Eich wrote:
To quote Waldemar from
"It's a judgment call, and I'd take these on a case-by-case basis. For const and let, I see little harm in browsers allowing them now in strict mode with the purely non-hoisting (C++-like) scoping rules, particularly if they complained when you accidentally declared a variable twice directly in the same block."
So the current idea is that ES.next has different syntax and semantics, and so in general the strategy would be to offer <script type="harmony"> and otherwise some form of "transpilation".
Right ("harmony" is a placeholder, the likely minimum but not best form would be type="application/ecmascript;version=6").
But you are also proposing to move some ES.next features into the existing ES5.1 strict mode already provided by implementations?
No. Rather, Harmony (which is opt-in per above) is based on ES5 strict.
Compiling from ES.next to ES5 is doable but it may not match the "transpiling" (ugly word) definition.
On Nov 16, 2011, at 4:18 AM, Erik Corry wrote:
In <script type=harmony> mode we plan to support the new non-hoisted semantics.
Block-hoisted -- temporal dead zone. Requires a sentinel value still in general. Hope this is not bad news!
On 16 November 2011 20:03, Brendan Eich <brendan at mozilla.com> wrote:
On Nov 16, 2011, at 4:18 AM, Erik Corry wrote:
In <script type=harmony> mode we plan to support the new non-hoisted semantics.
Block-hoisted -- temporal dead zone. Requires a sentinel value still in general. Hope this is not bad news!
Actually, it is almost done. We already fully implement "let" with temporal dead zone, and will shortly do so for harmony-mode "const" as well.
Awesome. SpiderMonkey better get its old let and const in gear :-P.
Hello,
Do I have it right that the intention with
let' and
const' is to allow them in strict mode?SpiderMonkey appears to allow them, as does V8 with --harmony, but V8 without --harmony and JSC both abort on `const' in strict mode.
Likewise, none of the major engines abort on
const' in non-strict mode. In non-strict mode in browsers, which semantics should
const' have? The old one, with hoisting?,
Andy