New private names proposal
Allen Wirfs-Brock
allen at wirfs-brock.com
Tue Dec 21 19:33:25 PST 2010
On Dec 21, 2010, at 5:57 PM, Brendan Eich wrote:
>>
>> A use directive feels vaguely more comfortable here to me. It makes it clearer to the programmer that some kind of magic is going on.
>>
>> But I confess that I haven't actually read Allen's proposal, so take this with a grain of salt.
>
> What's generative in JS already? Mutable object "literals":
>
> function f() {} // inside the outer myCoolFunction
> var o = {p:1};
> var a = [1,2];
> var r = /hi/; // thanks to ES5 recognizing reality over ES3
>
> That suggests the obvious:
>
> private cachedHotness = gensym();
>
> but then the gensym() initializer, which does indeed scream "new generated value here on every evaluation!", becomes both proper notice and (over time) deadwood, boilerplate. Plus, what's gensym calling? Maybe that built-in is shadowed.
>
> We could try shortening and using a keyword for unambiguous and novel generativity-here notice to readers:
>
> private cachedHotness = new;
>
> I admit, it looks weird. Lose the =, try for special-form syntax like a function declaration uses:
>
> private cachedHotness {};
>
> Does this "look generative"?
>
> How about a "more special" special form:
>
> new private cachedHotness;
>
> Not generative-looking enough?
>
> Discussion list fodder, glad we have es-discuss for this stuff.
>
> /be
This is a useful line of discussion. Up to this point there has been quite a bit of "I don't like the syntax in the private names proposal" but not a lot of suggested alternatives.
My request to anyone who wants some sort of private object state access is: propose the syntax you want to use.
In doing so, you will have do decide what constraints you are going to impose upon yourself. In the private name proposal, a constraint we imposed was that we would only use keywords that were already identified as future reserved words in the ES5 spec. That pretty much left "private" and "protected" as usable keywords. After some private conversations I concluded that "private" was probably going to be a better choice than "protected".
How much of the discomfort about the proposed syntax comes form implications associated the word "private"? What if we allowed expansion of the set of available keywords. Would any of the following be more comfortable:
property cachedHotness;
field cachedHotness;
name cachedHotness;
Alternatively, if we eliminated the ability to use dotted access syntax for private properties/fields we wouldn't need a declarator for at all. We could get by with something like:
const cachedHotness = gensym(); //this was new Name() in the original Names proposal
const obj = {};
obj[cachedHotness] = foo.hotness;
This still requires the ToPrivateName extension of the [ ] semantics described in the "Accessing Private Names as Values" section of the proposal. It eliminates the ability to say obj.cachedHotness and have it mean anything related to the value that was gensym'ed. obj.chachedHotness would always mean obj["cachedHotness"] exactly as it does now. It would also eliminate any scoping issues related to private names.
However, a consequence of eliminating the private declaration is that we also eliminate the obvious way to extend object literals to support private properties:
const obj = {
cachedHotness: foo.hotness //not the same as obj[cachedHotness] = foo.hotness; in the above example.
}
This seems quite undesirable as I think quite a few of us favor declarative object construction using object literals over imperative object construction.
There are a lot of trade-off like this that went into the private names proposal. I'd be happy to see other alternative complete proposals. I'm also happy to talk about the rationale behind each feature of the proposal and to consider alternatives. However, there are a number of inter-related design decisions and you can't necessarily change just one of them without impacting the others.
Allen
More information about the es-discuss
mailing list