Private Names in 'text/javascript'
Yes, I agree that separating them out is a good idea. Allen and I have been working on this lately, and I've signed up to present private names at the upcoming face-to-face. Our thinking has been along similar lines to what you describe here.
Great - I see the new unique_string_values strawman now. That looks like it does address the same goal. Happy to see there is already progress on this. Was there a particular reason for the shift to treating these names as a new kind of string value instead of as a separate object kind which could be used as a key in objects?
Yes (from my perspective) but it is something we are still hashing out so don't assume that will be the final proposal.
2011/5/18 Luke Hoban <lukeh at microsoft.com>:
The Private Names strawman currently combines a new runtime capability (using both strings and private names as keys in objects) with several new syntactic constructs (private binding declarations, #.id). At the March meeting, I recall there was some support for the idea of separating these two aspects, and exposing the runtime capability also as a library that could be used in ‘text/javascript’.
I'd like to support this idea.
Your example looks a bit wrong to me though. It seems to make new private names per object. Surely we want a private name per 'class' instead.
var Point = (function() {
var _x = Object.createPrivateName();
var _y = Object.createPrivateName();
var Point = function(x, y) {
this[_x] = x;
this[_y] = y;
}
Point.prototype.myMethodUsing_xAnd_y = function() {...}
return Point;
})()
var p = new Point(1, 2);
Separating out the functionality of abstract names certainly is a good idea.
But is there any reason to make it a method of Object? In essence, private names form a new primitive type, so there should be a separate global object or module for them. Assuming for a minute it was called Name (which clearly is a suboptimal choice), then you'd rather invoke Name.create(), or perhaps simply Name() (by analogy with calling String(v) to create primitive strings, although I'm not sure I like the notational abuse behind it).
It would be nice to do Name("foo")
or PrivateName("foo")
so that the
debugger has some name to use when displaying objects with private
fields. Alternatively, I suppose the debugger could guess the name
like it does currently for Foo.prototype.myFunc = function() ...
. This
has the disadvantage that a library that uses unique strings to
simulate some of the features of private names on older browsers would
not be able to give the unique names a meaningful prefix.
As Dave mentioned earlier in this thread he and I are still working on a unified proposal. Luke mentioned my latest working draft that tries to address some of the issue mentioned above. It is at strawman:unique_string_values. Note however, that this iteration is not necessarily what we will end up proposing.
In general, it is a good idea to avoid new global names that aren't going to be in modules. In particular, there is no particular reason these factory methods shouldn't be visible via the Harmony "ES5" global object. In that case hanging them off an existing constructor carries less risk of collisions (but not no risk) with user defined name. "Name" seems like it might be a particularly risky global to grab. Luke suggested hanging them off Object and in my working draft I suggest String. Either is probably safer than adding new globals.
Hm, making name creation a method of String
seems equally odd --
unless you also plan to have typeof String.createPrivateName() == "string"
.
Of course, I see the concern with the global object (although 'Name' was only a strawman suggestion). I assume that we need a future-proof solution for adding new built-in objects anyway, most likely based on modules. And that accessing built-in objects through the global object will be deprecated in Harmony code. So, since private names will be Harmony-specific, their constructor doesn't have to be visible through the "old" ES5 global object.
Wouldn't introducing a new built-in constructor in some module scope actually have less risk (none?) of producing name clashes than messing with an existing object?
Wouldn't introducing a new built-in constructor in some module scope actually have less risk (none?) of producing name clashes than messing with an existing object?
Yes, and I think it's worth considering. We still need to work out the organization of the standard library in modules.
On May 19, 2011, at 3:04 AM, Andreas Rossberg wrote:
Hm, making name creation a method of
String
seems equally odd -- unless you also plan to havetypeof String.createPrivateName() == "string"
.
That is indeed the plan in the particular version of the proposal that started this thread.
Of course, I see the concern with the global object (although 'Name' was only a strawman suggestion). I assume that we need a future-proof solution for adding new built-in objects anyway, most likely based on modules. And that accessing built-in objects through the global object will be deprecated in Harmony code. So, since private names will be Harmony-specific, their constructor doesn't have to be visible through the "old" ES5 global object.
This thread initially was specifically about how to make private name creation available in code that does not opt-in into new Harmony syntax.
On 19 May 2011 17:09, Allen Wirfs-Brock <allen at wirfs-brock.com> wrote:
That is indeed the plan in the particular version of the proposal that started this thread.
You mean the unique_string_values proposal that Luke mentioned?
Hm... Doesn't that have similar potential for breaking code? Existing code could make lots of assumptions about what it can do with a value if its type equals "string". Unless I misunderstand something, "secret" strings would break some of those (valid) assumptions.
This thread initially was specifically about how to make private name creation available in code that does not opt-in into new Harmony syntax.
My apologies, you are right. But how would such a proposal affect the Harmony side of things? Is the intention to have it replace a proper type of private names in Harmony, or merely complement it?
On Fri, May 20, 2011 at 8:26 AM, Andreas Rossberg <rossberg at google.com> wrote:
But how would such a proposal affect the Harmony side of things? Is the intention to have it replace a proper type of private names in Harmony, or merely complement it?
I'm not sure which proposal you're referring to here, but:
-
We certainly intend to only suggest one type of private name for promotion to proposal. Whether that's unique strings or objects isn't yet clear, but it would be very confusing to have two versions of private names.
-
Whatever we propose, if it ends up in Harmony, there will be a way for it be accessible from the non-Harmony heap, and therefore the proposal needs to work reasonably in both cases.
The Private Names strawman currently combines a new runtime capability (using both strings and private names as keys in objects) with several new syntactic constructs (private binding declarations, #.id). At the March meeting, I recall there was some support for the idea of separating these two aspects, and exposing the runtime capability also as a library that could be used in 'text/javascript'.
I added a comment to the Private Names strawman page to suggest how this could be done. The runtime behavior of the proposal is the same, but in addition, a library function
Object.createPrivateName(name)
is added which provides direct access to the internal CreatePrivateName abstract operation. This allows the use of private names in a more verbose form, but without needing new syntax - similar in spirit to the ES5Object.*
operations. Borrowing an example from the current proposal to illustrate:Using 'text/harmony' syntax:
Using 'text/javascript' syntax:
There seem to be several benefits to this: