Dave Herman wrote:
> I think you're still going to have the same subtleties as hoisting with
> this proposal, since all the variables assigned to in the block will be
> in scope for the whole block; so they'll be `undefined' before being
> assigned to and there will still be the same closure hazards where you
> might think the variable was in scope in a nested block but in fact it
> goes out to the nearest enclosing var { ... } block.
Actually, I forgot to mention that in there should no longer be any
hoisting in this case; it should be a syntax error:
blah = 10;
var {
print(blah);
blah = 20;
print(blah);
}
The first |print(blah)| should be a syntax error. I think this is what
Python does too.
> > var {
> > ...
> > nonlocal x [ = y];
> > ...
> > }
>
> For my tastes, this puts too much of a tax on referring to outer variables.
The alternative, which Pythonites have used for a while until the advent
of |nonlocal|, was to have an object/array in the outer scope and have
the outer variable be a property of that object:
var {
function outer() {
x = 10;
a = [x];
function inner() {
return a[0];
}
return inner();
}
}
However, this is pretty ugly and isn't very discoverable.
> These are the kinds of bugs that I think this semantics would result in:
> when assignment implicitly binds variables, fat-fingering an assigned
> variable name silently works and then causes unpredictable behavior
> later. Whereas with traditional lexical scope, when you declare your
> variables up front, both assignments and references are checked against
> the variables in scope, and you get an immediate error -- even
> statically detectable.
While this is true, this is far less of a problem than opt-in local
scoping, because the errors with opt-out local scoping are always going
to be local to the block/function the variable was assigned in.
Because of this, I believe the convenience is worth the cost.
> I don't believe that
>
> var {
> ...
> a = f()
> ...
> b = g()
> ...
> c = h()
> ...
> }
>
> is that much less of a hardship than
>
> {
> ...
> var a = f()
> ...
> var b = g()
> ...
> var c = h()
> ...
> }
>
> and I believe the benefits of a clearer semantics -- and clearer and
> earlier errors on assignment to free variables -- are worth it. But I
> agree that we need to do something to correct the semantics of looking
> up free variables dynamically.
I don't particularly like |var { ... }| myself, but it's the only other
way besides a pragma - I would much prefer a pragma, which would pretty
much eliminate the usage of |var|.
> > And finally, it would be nice to have a pragma that can do this for us
> > (again, I don't recall the argument against them). Something like:
> >
> > use scope var;
> > use scope let;
> > use scope nonlocal; // default for backwards compatibility
>
> Lexical scope is in the air. :) Please take a look at the lexical
> scope proposal on the wiki and offer any comments or suggestions:
>
> http://wiki.ecmascript.org/doku.php?id=strawman:lexical_scope
>
> Essentially, the above is a less radical proposal that simply uses the
> lexical scope that's already there in JavaScript, but as you suggest
> enforces it with a pragma. The result is a language where free
> variables, both in assignments and references, are a statically
> detectable error, but with otherwise essentially the same semantics that
> JavaScript already has.
>
> Dave
>
I've taken a look at that, and while it does address free variables, I'd
still rather not have to sprinkle redundant |var|s everywhere.
_______________________________________________
Es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss