Block scoping and redeclarations

Andreas Rossberg rossberg at
Tue Aug 23 05:31:24 PDT 2011

We are currently in the process of implementing block scoping for V8
Brendan and Dave suggest that certain combinations of `let' and `var'
should be an error (more precisely, a syntax error, I assume).
However, there are various possibilities to interpret this. Assume
that each line in the following is a function scope:

{ let x; var x }  // 1a
{ var x; let x }  // 1b

{ let x; { var x } }  // 2a
{ var x; { let x } }  // 2b

{ { let x } var x }    // 3a
{ { var x } let x }    // 3b

{ { let x } { var x } }  // 4a
{ { var x } { let x } }  // 4b

1a-2a should clearly be errors. Same for 3b arguably, because the var
is hoisted to the same scope as the let. In 2b, 3a, and 4a/b, a var is
shadowed by a let, which isn't a problem in principle. OTOH, strictly
speaking, at least 3a and 4a actually introduce a "var-declaration
that has already been shadowed by a let-declaration" (Dave's words).

There are lots of arguments that can be made here, but ultimately, my
feeling is that any rule that allows some of the examples above, but
not others is both brittle and confusing, and potentially too
complicated to memoize correctly for the average programmer.
Consequently, we propose a very simple rule instead:

* It is a syntax error if a given identifier is declared by both a
let-declaration and a var-delaration in the same function. (And
similarly, for const vs. var, or function vs. var -- the latter being
an incompatible change for the global scope, but it seems like we may
abolish that anyway.)

We could go even further with the first point: we could make it a
syntax error to mix var and let _at all_ in a single function,
regardless of what identifiers they declare. I would be perfectly fine
with that, too, but expect that others would disagree.

* In a similar vein, I think we should probably forbid `var' to
coexist with _any_ other form of binding for the same variable in a
single function. In particular, for Harmony mode we should rule out
the infamous "try .. catch(x) { var x = 666; ...}".

* Finally, do we allow redeclaring functions with let or const, like
it used to be the case with var? I propose disallowing it.

What do you think?


More information about the es-discuss mailing list