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.

  but depending on which case executes first, this may or may not trigger an 
error on accessing x before it is defined.  This is the only place in the 
language where a reference to a let binding declared in the same block scope as 
the reference cannot be statically understood to be a valid vs. invalid read.

Sure, but why did you exclude closures?

Closures can nest in blocks and capture let and const, and use a let or const binding before it has been initialized. Closures are a big part of JS. The "declared in the same block ... as the reference" is therefore too narrow as an objection to the infeasibility of statically analyzing let-in-switch.

Without such narrow special pleading, we have with the temporal dead zone a use-before-init rule that cannot be statically analyzed, period. Closures are enough, switch is not novel. If it has other issues, let's argue about them, but this one is off target due to closures.

   This is both likely to cause confusion for developers, and adds 
implementation complexity.

Not in our actual, >5-years-long experience. Examples:

http://dxr.mozilla.org/mozilla-central/b2g/chrome/content/forms.js.html#l50
http://dxr.mozilla.org/mozilla-central/b2g/chrome/content/shell.js.html#l290
http://dxr.mozilla.org/mozilla-central/b2g/chrome/content/shell.js.html#l300
http://dxr.mozilla.org/mozilla-central/b2g/chrome/content/shell.js.html#l301 etc.
http://dxr.mozilla.org/mozilla-central/toolkit/components/places/nsPlacesExpiration.js#l931
http://dxr.mozilla.org/mozilla-central/services/sync/modules/engines/tabs.js#l303
and many others...

Programmers can do this with var and they expect to do the same with let.

There's an argument to be made that switch case StatementLists should not be 
allowed to include Declarations.  This would make the code above a syntax 
error, and require putting {} around the case if 'let'/'const' were needed.

We considered that back in the ES4 era, but it is onerous. Lots of vars in sub-statements, and people reasonably expect to write let declarations the same. There is a braced body-block to scope such let declarations. Typically the case "arms" have disjoint declarations, and programmers definitely know to use a block to avoid colliding.

   This also aligns with all other occurrences of nested statements that are 
not surrounded by {} in the grammar, for example, 'if(true) let x = 3'.

Yes, but switch is different. It has a braced body. Its statement-lists have fall through so the more relevant "if" comparison would be something like

  {
    let x = 42;
    if (y)
      x = 43;
    alert(x);
  }

which is perfectly legal in ES6 and any Harmony or ES4-era proposal.

   Current Chrome builds appear to follow this approach, reporting that the 
'let' in the initial code sample above appears in an 'unprotected statement 
context'.

Are we all trying to follow the draft spec, or not? Thanks for proposing to change it first. Implementations deviating without talking first = disharmony.

/be
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to