Block scoping and redeclarations

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


On 24 August 2011 18:03, Brendan Eich <brendan at mozilla.com> wrote:
> On Aug 24, 2011, at 2:03 AM, Andreas Rossberg wrote:
>> On 23 August 2011 21:18, Brendan Eich <brendan at mozilla.com> 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
cases.

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.

/Andreas


More information about the es-discuss mailing list