Block scoping and redeclarations

Andreas Rossberg rossberg at
Thu Aug 25 06:17:55 PDT 2011

On 24 August 2011 18:03, Brendan Eich <brendan at> wrote:
> On Aug 24, 2011, at 2:03 AM, Andreas Rossberg wrote:
>> On 23 August 2011 21:18, Brendan Eich <brendan at> wrote:
>>> I think the rules we have discussed are:
>>> 1. Any hoisting of var across let binding the same name (whether explicit, or as in catch blocks and comprehensions, implicit) is an early error.
>>> 2. Redeclaration of a name in the same block scope via let, const, or function-in-block is an error.
>>> That's it. Shadowing via let, const, and function-in-block is allowed (alpha conversion).
>> That's fine, although for (1) you probably meant "hoisting of var
>> across a scope that contains a let binding the same name" (or, if you
>> assume that let is hoisted to the beginning of its block already, then
>> you have to be very careful about specifying the exact order in which
>> all the hoisting happens).
> It doesn't matter whether the hoisting is in the same block, or the var is in a block nested within the let's block (or body) scope.
>> And for (2), you have to specify whether
>> this applies before or after hoisting. In fact, I think it's both,
>> since I assume that we want to make both of these an error:
>> { let x; { var x } }
>> { { let x; var x} }
> There is no "before and after" or "both" here. Hoisting first, with rule 1 enforced; then rule 2 checking. Relative source order of declarations is irrelevant.

<pedantic>Well, only when you're implicitly assuming a somewhat
non-standard meaning of "across", as rather "across or from".
Clarifying that amounts to the same thing.</pedantic>

>> Also, I wouldn't necessarily have regarded catch variables as
>> "implicitly let-bound". Seems a bit odd, but I guess it's OK to define
>> it that way if it does the right thing.
> That is explicit in ES3-in-reality (ES3 was broken), real engines use block scoped catch variable bindings, and those engines that support 'let' (Rhino and SpiderMonkey at least) use exactly the same block-scoping machinery for catch variables as for let bindings.
> We went over this during ES3.1 and ES4 days, here on-list and in TC39 meetings. No problem reiterating, I realize that was long before your time :-).

Sorry for digging up old bones then. :) Not a big deal, I just wasn't
aware that you seem to be equating "let-bound" with "block-scoped".
That's a bit surprising for the uninitiated.

>> Does it really harm migration? I can see only two scenarios that would
>> end up with an illegal redeclaration:
>> 1) The original function contained a single var x somewhere, and
>> somebody is adding a let x now -- this is no big deal, since it is a
>> new variable anyway and can easily be chosen differently. (And in
>> general, it has to anyway; perhaps better to have a uniform rule of
>> thumb here.)
> This costs, you are special-pleading. Oh, migrators can absorb *my* preferred tax, for the greater good *I* see. That's not how the game is played.

Fair enough. My main point here was that migrators are generally
paying that tax anyway, we are just talking about a tax cut for some

Anyway, I'll rest my case. I remain somewhat unconvinced that the
extra complexity is nil and worthwhile, but there obviously are more
critical topics. We'll go ahead and implement the rules that you
sketched above.


More information about the es-discuss mailing list