On Aug 9, 2012, at 8:48 PM, Brendan Eich wrote:
> Luke Hoban wrote:
>> According to the current draft spec text 'let'/'const' are allowed in the
>> statement list of a switch case, but contribute to the block scope of the
>> outer block. This can lead to some confusing situations:
>>
>> function(x) {
>> do {
>> switch(x) {
>> case 0:
>> return x;
>> case 1:
>> let x = 'let';
>> }
>> } while (foo());
>> }
>>
>> The 'x' in 'case 0' here will bind to the later 'let x',
>
> That's right, let hoists to braced body or block top -- explicit is better
> than implicit.
>
> I did this in JS1.7 and we've had years of experience with it, in
> SpiderMonkey and Rhino. Alternative of implicit per-"case" scope does not
> work due to C-like fall-through inherited via Java. Programmers do write let
> in case- and default-labeled statement lists in switches in Mozilla-specific
> code and I've never heard of a usability problem.
>
> We could be restrictive (more below), but you have to make a usability or
> implementation hardship case. I don't think you have.
A more illustrative example for Luke's concerns would be:
function(x) {
do {
switch(x) {
case 0:
return x; //always a runtime error
case 1:
let x;
x = 'let'; //never a runtime error
case 2:
return x; //sometimes a runtime error
}
} while (foo());
}
The classifications (always, never, sometimes) of references can be determined
by a fairly straightforward static analysis. You only need to do a runtime TDZ
check on the sometimes case. You can issue compile-time warnings on the always
and sometimes cases.
>From a usability case we have to consider which is more likely something like
>the above or something like:
switch (x) {
case 0:
let a = ...;
// lots of lines of code using a
break;
case 1:
let b = ...;
// lots of lines of code using b
break;
case 2:
...
}
My guess was that the disjoint case would be more common and more annoying if
it was disallowed. I considered spec'ing each case alternative as a block but
I concluded it would be unwise to introduce a block scope that was not
associated with { }'s.
Basically, the switch body is a block and all the static semantic rules for
blocks apply to it as do the same dynamic initialize-before-reference TDZ
rules. This seems straightforward enough to explain to users. The only oddity
is that it has multiple entry points which means some TDZ violations can't be
be statically predicted, but that is an optimization issue rather than one of
user understanding.
Allen
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss