New private names proposal

David Flanagan david at davidflanagan.com
Tue Dec 21 23:00:30 PST 2010


Brendan wrote:
>> >   use private cachedHotness;
> We have that kind of syntax reserved for pragmas:

I know, and that is why I threw it out there.  To me, this kind of 
messing around with the meaning of identifiers feels like a compile-time 
thing, not a runtime thing...  Allen's proposal treats "private" like 
"var" and "const", and it makes me uneasy because it seems as if there 
is something deeply non-parallel there. More below, but for now, I 
withdraw the "use private" suggestion.

On 12/21/2010 07:33 PM, Allen Wirfs-Brock wrote:
> My request to anyone who wants some sort of private object state access is:  propose the syntax you want to use.

Okay.  I've read the strawman now, and I'm ready to make a sketchy proposal:

What we do currently for weak encapsulation (where currently weak means 
advisory only) is prefix our identifiers with underscores. I would like 
it if the private names syntax just made something like this work to 
give us a stronger form of weak encapsulation.  The strawman already 
uses the # character, so let's stick with that.  I propose that if you 
prefix an identifier with #, you get a private name:

     var counter = {
        #count: 0;
        next: function() { return this.#count++; }
        reset: function() { this.#count = 0; }
     };

This is just what we might write today, but with # instead of _.

In order for this to work you have to abandon the idea of scoped private 
identifiers.  I say: make all private identifiers scoped to the 
compilation unit. Names wouldn't be private within a file or <script> or 
eval'ed string, but they would be private across files. Given that this 
encapsulation can be defeated with Object.getOwnPropertyNames anyway, 
and given that programmers who really need within-file privacy can skip 
this convenient syntax and create their own Name objects, I think this 
ought to be good enough.  (Though it does have important consequences 
for script concatenation.)

The second part of my proposal is a little more shaky. The # token, by 
itself, would evaluate to an opaque value such that:

      o.#foo === o[# + "foo"]

This means that to share private names (all of them) across compilation 
unit boundaries, you'd share the # value.  (I'm not sure whether I'd 
propose that Allen's #.foo syntax for converting just a single private 
identifier to a Name object be retained or discarded.)

Note that this addresses the concern Oliver raised about accidentally 
generating new private names on each invocation of a constructor.  With 
this proposal, #foo means the same thing everywhere and on every 
invocation within a compilation unit.

Also note that the use of the # prefix removes the need for the whole 
"Private Declarations Exist in a Parallel Environment" section of the 
strawman.

	David


More information about the es-discuss mailing list