Uniform block scoping

Brendan Eich brendan at mozilla.org
Wed Aug 13 16:27:56 PDT 2014


Andreas Rossberg wrote:
>> In particular,
>> >
>> >  function f(a) {
>> >     ... // TDZ
>> >     let a = ...;
>> >     ...
>> >  }
>> >
>> >  and
>> >
>> >  function g() {
>> >     try {
>> >       ...
>> >     } catch (e) {
>> >       ... // TDZ
>> >       let e = ...;
>> >       ...
>> >     }
>> >  }
>> >
>> >  should be early errors because there's no useful shadowing going on with
>> >  'let' -- the TDZ means the outer binding cannot be used in the commented
>> >  places -- but any prior version using 'var' would have worked and possibly
>> >  allowed (coverage-dependent) uses of the "outer" (in catch's case, var
>> >  hoists across the catch head in sloppy code; in the parameter case there's
>> >  only ever one 'a' binding) use in the TDZ.
>> >
>> >  So an early error does no actual harm in either case, and helps avoid bugs
>> >  slipping past incomplete test coverage.
>
> Well, this is a valid concern, but I'd like to point out that it is a
> flawed argument for defending the status quo.
>
> If we really cared about legacy refactoring mistakes going unnoticed,
> then the suitable (and consistent) semantics would be to make_all_
> intra-function shadowing (or more precisely, multiple declarations) an
> error. Otherwise, we are just picking random cases. For example, I
> don't see how the above argument can justify the current discrepancy
> between these two:
>
>    for (let x ...) { let x; ... }  // fine
>    try ... catch(x) { let x; ... }  // error
>
> The former is just as much a potential bug as the latter, or as all
> other cases of redeclarations.

You're right, if the issue is shadowing an immediately enclosing 
binding. The param vs. var-ported-to-let case is different because the 
var does not shadow and this is observable via sloppy mode arguments 
object element / formal parameter aliasing.

But even in the catch case, in sloppy code with var x in the catch 
block, latent bugs are likely to lurk due to hoisting.

So the rationale is not that immediate-shadowing per se should be an 
error -- it is rather that var-cum-let bindings that tangle with or 
cross over a legacy danger zone (formal parameter aliased by var; 
implicit let binding in catch head) should be errors.

Macros and similar systems could very well want immediate let-bound 
shadowing within a block that is self-contained, in new code. We don't 
believe all such cases should be errors.

Does this help?

/be



More information about the es-discuss mailing list