Conflicting declarations -- Was: Re: local
On Aug 22, 2008, at 7:26 AM, Ingvar von Schoultz wrote:
Brendan Eich wrote:
More helpful would be comments on the utility of let blocks
(a.k.a. let statements) and let expressions.While reading up on this, I noticed that you can declare the same name with both let and var in the same scope:
var x = 'global'; let x = 42;
If these are both within an explicit block, the let will shadow the
hoisted var.
Even if you do this in the global scope or function top level, both will exist, in the same scope, one shadowing the other (but details differ between texts and test results).
This past April at the ES4 WG meeting we decided to make let equate
to var at top level within a function body or program. This is not
what JS in Firefox 2 and 3 do in functions, but it is what the
SpiderMonkey implementation does at top of program. We are fixing
things to match the latest proposal all around.
Another thing we do that's a bit harsh is to call repeated let x;
declarations in the same explicit block an error.
In my opinion this is not a useful feature, quite the contrary. If the variables are far apart on the page, the disappearance of one of them will be mysterious and difficult to debug.
It's also a pain to implement in few passes at top level, if one
prefers to parse a top-level statement at a time and recycle the AST
after generating code.
In the special case of global and function-top-level scope, intuitively let and var seem synonymous.
Agreed, and that's what Firefox 3.1 will do.
But throwing an error seems fine too.
{ let x; { var x = 10; } }
The let hides the var. This should throw an error too, as I see it. If a name can't be reached where it's declared, that's hard to debug.
Could be -- thanks for the feedback.
Brendan Eich wrote:
On Aug 22, 2008, at 7:26 AM, Ingvar von Schoultz wrote:
Brendan Eich wrote:
More helpful would be comments on the utility of let blocks
(a.k.a. let statements) and let expressions. While reading up on this, I noticed that you can declare the same name with both let and var in the same scope:var x = 'global'; let x = 42;
If these are both within an explicit block, the let will shadow the
hoisted var.
This one is bizarre and infrequent enough that I wouldn't mind if we made this into an error -- specifically, you can't write "var x" inside a block that contains a "let x" if that var would hoist to or beyond that let's block.
Waldemar
I agree that this should be a static error.
Brendan Eich wrote:
This past April at the ES4 WG meeting we decided to make let equate to var at top level within a function body or program.
That's good news.
Another thing we do that's a bit harsh is to call repeated let x; declarations in the same explicit block an error.
This is good for big projects that need discipline and organization, /if/ the compiler throws an error on undeclared variables. But as I've mentioned elsewhere, I see important drawbacks in the opposite cases.
I think it would be a good idea to consider varying this between subset cautious and subset reckless.
(Well it needs a name, doesn't it?)
On Aug 22, 2008, at 7:26 AM, Ingvar von Schoultz wrote:
In my opinion this is not a useful feature, quite the contrary. If the variables are far apart on the page, the disappearance of one of them will be mysterious and difficult to debug.
It's also a pain to implement in few passes at top level, if one prefers to parse a top-level statement at a time and recycle the AST after generating code.
I'm surprised, I thought making synonyms would be easy.
On Fri, Aug 22, 2008 at 12:40 PM, Waldemar Horwat <waldemar at google.com> wrote:
Brendan Eich wrote:
On Aug 22, 2008, at 7:26 AM, Ingvar von Schoultz wrote:
While reading up on this, I noticed that you can declare the same name with both let and var in the same scope:
var x = 'global'; let x = 42;
If these are both within an explicit block, the let will shadow the hoisted var.
This one is bizarre and infrequent enough that I wouldn't mind if we made this into an error -- specifically, you can't write "var x" inside a block that contains a "let x" if that var would hoist to or beyond that let's block.
On Fri, Aug 22, 2008 at 2:04 PM, Mark S. Miller <erights at google.com> wrote:
I agree that this should be a static error.
Even this simple cleanup has surprising consequences. If
function() { ... { var x = 'global'; let x = 42; } }
is a static error, then so should
function() { ... { var x = 'global'; const x = 42; } }
and
function() { ... { var x = 'global'; function x() 42; } }
The last of these differs from the current behavior 4/4 existing browsers. However, I still think it's the right thing, and it is upwards compatible from ES3 (which prohibits nested named function declarations).
Brendan Eich wrote:
While reading up on this, I noticed that you can declare the same name with both let and var in the same scope:
Even if you do this in the global scope or function top level, both will exist, in the same scope, one shadowing the other (but details differ between texts and test results).
In my opinion this is not a useful feature, quite the contrary. If the variables are far apart on the page, the disappearance of one of them will be mysterious and difficult to debug.
It becomes trivial to solve if instead an error is thrown, reporting conflicting declarations.
In the special case of global and function-top-level scope, intuitively let and var seem synonymous. But throwing an error seems fine too.
The let hides the var. This should throw an error too, as I see it. If a name can't be reached where it's declared, that's hard to debug.