New private names proposal
Peter van der Zee
ecma at qfox.nl
Wed Dec 22 07:10:28 PST 2010
On Wed, Dec 22, 2010 at 3:26 PM, David Herman <dherman at mozilla.com> wrote:
>
> As for the complaint of it being over-generative, that's mitigated in this
> case by the sigil. For example, if you wrote:
>
> function Point(x, y) {
> private #x, #y;
> this.#x = x;
> this.#y = y;
> }
> Point.prototype = {
> ... #x ... #y ...
> };
>
> you'd get a compile-time error since #x and #y aren't in scope. Unless, of
> course, they are already in scope as another private, although I'd expect
> this kind of thing to be a bit rarer than variable scope errors since I
> would guess private names wouldn't be nested and repurposed as often as
> variables -- that's just a guess; it's hard to be sure.
>
What about adding an attribute to properties that somehow identify which
classes (in the prototype chain for protected) have access to the object?
I'll leave the "somehow" up in the air, but you could introduce a
[[Private]] attribute which, if not undefined, says which context must be
set (and for protected, either directly or through the prototypal chain of
the current context) to gain access to this property. And if that context is
not found, some error is thrown. Maybe it would be [[EncapsulationType]] ::
{private, protected, public} and [[EncapsulationContext]] :: <?>. You could
also add a simple api to check for these (isPrivate, isProtected, isPublic,
hasEncapsulatedProperty, etc) depending on how it would affect "in" and
enumeration.
Pro's:
- meaning of private will be more to what people expect
- minimal "magic" going on, trying to access a private property out of scope
should result in a proper error
- possibly less impact on the spec (although I'm not sure there...)
- no need to introduce a new type/class to denote private properties
Con's:
- what should be the value of [[Private]]
- there are probably still complications in the specification
- "weak encapsulation"
Unknowns:
- what about inheritance and prototype?
- in, enumeration, etc?
I don't really see weak encapsulation as an issue. If you really want
unreachable variables you can use a closure. In that regard, it seems to me
like the private keyword wouldn't really add anything new.
Syntactical specs aside, it would be something like this:
function F(n){
private x = n;
// private this.x = n;
// this.#x = n;
// .. or whatever
}
F.prototype.set = function(n){ this.x = n; };
F.prototype.get = function(){ return this.x; };
// the method does not carry the "private" burden
F.prototype.get.call({x:13}); // 13, this is fine because the property being
accessed was never defined to be private
// simple access of private x
var f = new F(10);
f.set(20); // ok
f.get(); // 20
log(f.x); // error, accessing private property x
// global function that doesn't inherit
function fail(){ return this.x; }
fail.call(f); // error, fail is not allowed to access private variable x
// G, child of F
function G(){}
G.prototype = new F(16); // (G.prototype.x becomes 16? or remains
undefined?)
G.prototype.test = function(){ this.x = 4; };
var g = new G();
g.test(); // is ok? or need to make "protected" distinction?
fail.call(g); // fail, accessing private x
Again, not proposing syntax. Not stepping into that minefield ;)
I personally don't like adding more magic to the language. Adding fields
that do or don't exist depending on context, especially when we have to
create a new type or class for it, doesn't seem to be in line with the
language. Having it throw an error on bad access seems better to me, and not
something that's unexpected. That way the field will still always exist when
it would in current contexts. It would simply not be read/write-able from
all contexts that properties are currently.
It would not be strong encapsulation (as demonstrated) but we already have
a truly strong method of encapsulation (closures). Is it really worth it to
drastically change the specification just to add the "classic" notion of
private? In all the (recent) threads, I've not yet seen another reason to
include it.
And I'd rather introduce a new attribute than a new global magic auto-type,
to handle the "being private" part of this strawman.
- peter
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20101222/996a1fb4/attachment-0001.html>
More information about the es-discuss
mailing list