Private Names in 'text/javascript'

# Luke Hoban (14 years ago)

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 ES5 Object.* operations. Borrowing an example from the current proposal to illustrate:

Using 'text/harmony' syntax:

  function Point(x,y) {
     private x, y;
     this.x = x;
     this.y = y;
     //... methods that use private x and y properties
  }
  var pt = new Point(1,2);

Using 'text/javascript' syntax:

  function Point(x,y) {
     var _x = Object.createPrivateName("x");
     var _y = Object.createPrivateName("y");
     this[_x] = x;
     this[_y] = y;
     //... methods that use private _x and _y properties
  }
  var pt = new Point(1,2);

There seem to be several benefits to this:

  1. The private name capability can be made available to 'text/javascript'
  2. The feature is easily feature-detectable, with a fallback of using '_'-prefixed or similar pseudo-private conventions
  3. The core functionality can potentially be agreed upon and implemented in engines earlier than full new syntax
# David Herman (14 years ago)

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.

# Luke Hoban (14 years ago)

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?

# Allen Wirfs-Brock (14 years ago)

Yes (from my perspective) but it is something we are still hashing out so don't assume that will be the final proposal.

# Erik Corry (14 years ago)

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);
# Andreas Rossberg (14 years ago)

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).

# Erik Corry (14 years ago)

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.

# Allen Wirfs-Brock (14 years ago)

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.

# Andreas Rossberg (14 years ago)

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?

# David Herman (14 years ago)

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.

# Allen Wirfs-Brock (14 years ago)

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 have typeof 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.

# Andreas Rossberg (14 years ago)

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?

# Sam Tobin-Hochstadt (14 years ago)

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:

  1. 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.

  2. 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.