(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