(Note that this topic is on the agenda for this month's TC39 meeting)
(Also, note that as far as I can tell, the disagreement is only about the early 
errors described below. The use of a separate parameter scope that limits what 
closures in parameter expressions can capture  has been agreed upon and is 
already in the ES6 draft spec.)

Everything would be so much cleaner if all we had were strictly lexically 
scoped declarations and no legacy to deal with...

Consider,

We've decided that that we don't want to allow multiple declarations for the 
same name in a scope:

function f() {
    let x;
    const x;  //early redeclaration error
}

function f() {
  let x;
  var x;  //early redeclaration error
}

function f() {
    let x;
    function x() {};  //early redeclaration error
}

We don't even have a runtime semantics for any of the above duplicate 
declarations.

Except that for legacy reasons we have to allow:
function f() {
    var x;
    function x() {}; 
    function x() {};  
    var x;
}
using the legacy ES semantics. 

The legacy ES semantics also requires that:

function f(x) {
   var x;   //not an error
   console.log(x);
}
 f(1);  //logs 1, not undefined

just like:

function g(x) {
   console.log(x);
}
g(1);  //logs 1

In other words, from the perspective of  the body of the function, the 
following two declarations appear to be equivalent:
function f(x) {
}
function f(x) {
   var x;  
}

But we've already established this is an error:
function f(x) {
   var x;
   let x;  //early error, duplicate definition
}

and if that is an error, then its equivalent alternative form should also be an 
error:
function f(x) {
   let x;  //early error, duplicate definition
}

And that is the crux of the disagreement. 

Andreas would like to reason about ES scoping as simple nested block contours 
with shadowing.  But the reality  is more complex than that.  We have vars 
declarations the hoist to the top level.  We have interactions between formal 
parameters and var declarations that interact with outer scopes (that are inner 
relative to the parameters if you think of the parameter list is a distinct 
scope contour).  In fact, in my current working draft, 
FunctionDeclarationInstantiation is almost 3 pages of detailed algorithmic 
specification. (and adding a parameter scope didn't simplify things...).

We really don't want the average (and certainly not the novice) ES programmer 
to have to understand all the technical subtleties of these interactions. It's 
much easer to have a few simple rules that states which declarations are legal 
and which declarations are not.  The rules are:

   It is illegal  for let/const/class declarations at the top level of a 
function to multiply define the same name.
   It is illegal  for a let/const/class declaration at the top level of a 
function to define the same name as a top level function declaration. 
   It is illegal  for a let/const/class declaration at the top level of a 
function to define the same name as a var declaration that occurs anywhere 
within the function body.
   It is illegal  for a let/const/class declaration at the top level of a 
function to define the same name as a formal parameter of the function.

This is what the ES6 spec. currently says (using slightly different words). 
Andreas would like to eliminate that lat rule. I think it should remain, both 
for the specific equivalence discussed above and for overall simplicity.  

> In terms of spec, this simply amounts to dropping several bullet
> points imposing syntactic restrictions about LexicallyDeclaredNames
> [2] -- i.e., simplification :). (Note: The legacy rule that legal ES5
> function declarations are var-like, not lexical, would of course be
> unaffected.)

It's actually not quite that simple.  There are a number of places where the 
specified runtime semantics are simplified because it is known that early error 
rules have eliminated various possibilities, such as parameter/let naming 
conflicts.  So, if we made this changeI will need to review all the relevant 
runtime semantics and look for newly exposed cases that need to be handled. 

More on catch clauses and catch parameter scoping in a seperate message. 

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

Reply via email to