On Sep 30, 2011, at 7:57 PM, Erik Arvidsson wrote:
> One of the things I like about the object literal syntax is that it
> doesn't seem like things might be in scope. Take this example (with
> intentional error):
>
> class Point {
> var x = 0;
> var y = 0;
> distance(other) {
> return Math.sqrt(x * other.x + y * other.y);
> }
> }
>
> it is very tempting to think that var x and var y are in scope. If an
> object literal is used at least we have the current behavior to steer
> people into doing the right thing.
Two thoughts:
1. Oliver and others do want x and y to be in scope somehow. They can't be via
the |this| parameter object on the scope chain, though. That's dynamic scope
(the prototype is extensible, or *a* prototype, possibly Object.prototype, is).
But the desire to avoid this. prefixing is natural and predictable for people
coming from C++, Java, etc. Should we consider supporting this expectation
somehow, rather than steering people away from it with less natural syntax?
2. The variant Bob and I were hacking on just now allows class data properties
to be declared using const or var (shall we say, let). This still can lead to
the expectation that class property names are in scope for class methods, or
even all methods. Bob's constructor set class.lastPoint = this; but for some
folks (Java heads), it would be more natural to set lastPoint = this. I'm not
defending, just noting the declaration implies name is in scope problem you
cite applies to class: properties in the variant proposal.
If we wanted to support x and y bindings in methods as lexical aliases to
this.x and this.y, given declarations, could we do it? Doing this would hide
any outer x and y. Same question goes for lastPoint, although it seems to me we
are free to shun the Java influence by not aliasing unqualified lastPoint to
Point.lastPoint in prototype methods. We could alias class property names in
class methods too.
What does it mean to alias properties with lexical bindings? The referent
properties' object must outlive the lexical scope. That's easy with |this| in
method activations, and I think also can be arranged for the class within a
class method.
Another implication is that the referent properties are non-configurable. That
leaves writable: true, which creates an alias analysis problem. Any property
reference in a method, say foo.x, could alias the storage referenced by lexical
x, to wit: this.x. So reads and writes would have be coherent, a challenge to
optimizing JIT-based VMs. Not a huge problem for implementors, but could this
make for confusion among users because x = 42 updates this.x?
See
http://wiki.ecmascript.org/doku.php?id=discussion:block_expressions#let_ref_as_a_reformed_with
where Lars Hansen mused about Modula 3's WITH statement, which does alias
fresh lexical names to variables including writable variables.
Adding lexical aliases to certain properties does add new semantics. Dave
reminded us (me anyway) at last week's TC39 meeting that we do not rule out new
semantics if warranted, we simply prefer desugaring to existing kernel
semantics where that works, and we try hard to avoid additions.
My question for everyone: will users expect declared property names to be
in-scope, no matter what the syntax for declaring or defining them is? I
suspect so, and that makes me think we're not going to do well by
"counter-steering" with object literal property init syntax.
/be
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss