January 19 meeting notes

Allen Wirfs-Brock allen at wirfs-brock.com
Fri Jan 20 11:51:06 PST 2012


On Jan 20, 2012, at 10:19 AM, Andreas Rossberg wrote:

> On 20 January 2012 18:28, Allen Wirfs-Brock <allen at wirfs-brock.com> wrote:
>> 
>> On Jan 20, 2012, at 7:13 AM, Wes Garland wrote:
>> 
>> On 20 January 2012 09:22, Herby Vojčík <herby at mailbox.sk> wrote:
>>> 
>>> 
>>> +1. I see no point why let e; should not shadow argument e here.
>> 
>> 
>> I do.  It is a virtual certainty that this form was used accidentally by the
>> developer, which indicates a flaw in the developer's thinking -- probably
>> due to cut-paste/refactor code having a variable name collision.  It should
>> be an early error/warning, just like it is in C.
>> 
>> This was essentially the conclusion that was reached when this was discussed
>> at the Nov. TC39 meeting.
> 
> How is
> 
>  function(x) { let x }
> 
> any different in this respect from
> 
>  { let x { let x } }
> 
> ? The same argument can be made in either case. The latter is allowed,
> the former isn't. In both cases, a block-local let shadows a variable
> from outer scope.
> 
> /Andreas
> 

This is a suability issue. Languages with c-like syntax seem to generally disallow top level re-declarations of formal parameters, even when they other support block scoped declarations.  Presumably because it is assume that shadowing probably not the user intent in most such situations.  I researched this last year and captured it in a email exchange I had with Brendan:

On Jun 8, 2011, at 11:23 AM, Allen Wirfs-Brock wrote:

> 

> On Jun 8, 2011, at 10:48 AM, Brendan Eich wrote:

> 

>> On Jun 8, 2011, at 10:28 AM, Allen Wirfs-Brock wrote:

>> 

>> 

>>> Does the semantics have any utility:

>>> I don't believe there is any utility in:

>>>    function (x) {let x=; ...}  

>>> it simply makes the formal x inaccessible.   In all probability this is really a coding or refactoring error.

>> 

>> That's not the case that arises from the let* semantics we (almost, you demurred after the meeting) agreed on last September at Mozilla:

>> 

>>  function (x) {foo(x); let x = bar(); baz(x);}

>> 

>> Here (and imagine it is a bigger function), the let semantics from last fall would make a new scope at the let x, as if there were an explicit { before it and one to balance at the end.

>> 

>> Users of C++ would be surprised, I think, if they couldn't write something like this. Not that C++ users get undue weight, but you get my point: it depends on what language(s) you are coming from.

> 

> According to the C++ specification rule I cited in my message the C++ equivalent to the above function would be an error because it redeclares a parameter name at the top level. Throw an extra level of { } around the function body and the results would be different. It would also be an error in Java and C#.  


I think there is strong precedent and good usability reasons for treating the formal parameter list and the top-level function scope as if they were the same "lexical name space".  EG, the top level function body is not allowed to shadow (or redeclare) formal parameters.  Also, there are backwards compatibility requirements (even in strict mode)  that function top level var statements and function declarations  are able to change the values of formal parameters. These are defined as SetMutableBinding operations not as creating new bindings.

This is a recurring discussion.  The discussion always seems to resolve (perhaps with some unhappy acquiesce) that we want to follow the C++/Java/C# (and other similar language) precedent adjusted to deal with legacy var and function semantics. 

Allen







-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20120120/b6320ae6/attachment.html>


More information about the es-discuss mailing list