About private names

Andrew Dupont mozilla at andrewdupont.net
Sun Mar 20 19:40:18 PDT 2011

First of all, let me be clear: my objections are only as deep as the syntax layer. I'm not arguing against the usefulness of private names as a concept.

On Mar 20, 2011, at 6:51 PM, Brendan Eich wrote:

> I encourage folks to read the private names thread from late last year, since we are revisiting the points made then:

OK, I read through the December thread. Let me pull out some of the highlights:

David-Sarah Hopwood said:
> I don't like the private names syntax. I think it obscures more than it
> helps usability, and losing the x["id"] === x.id equivalence is a significant
> loss.

This is exactly how I feel. Yes, I realize that these aren't exactly equivalent, so let me state it another way: right now, bracket notation is a superset of dot notation, but it would no longer be under the proposed syntax. I, too, feel that that's a significant loss in simplicity and isn't worth the trade-off.

Brendan said:
> That is, without private_names, the "p" in the expression |o.p| is literal
> text, not lexically bound as it could be via a prior |private p|.

This gets at my other objection. Code is far harder to debug when every single property lookup could have a meaning other than its plain appearance, depending on the existence of `private` declarations earlier in the scope.

Allen Wirfs-Brock said:
> 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.

My suggestion would be to remove `private`'s ability to affect dot notation and object literals _in any way that can affect users' existing JavaScript knowledge_. In other words, the current syntax changes the meaning of the simple `Foo.bar` that we're all accustomed to writing; this wouldn't be an issue if new syntax were involved.

For example, here's an altered version of the first example in the strawman, with comments to indicate what I've changed:

    function makeObj() {
       private unique;
       var obj = {};
       obj[#.unique] = 42; // was `obj.unique = 42;`
       print(obj[#.unique]); // 42
       print(obj.unique); // undefined (was 42)
       return obj;
    var obj = makeObj();
    print(obj["unique"]);  // undefined -- the name of the property is still not the string "unique"
    print(obj.unique);     // (ditto)
    print(obj[#.unique]);  // undefined -- we're in a different scope

This preserves the existing behavior of dot notation (as a literal property lookup by IdentifierName) and extends the behavior of bracket notation in a logical manner (as a superset of dot notation).

(I also would have no problem with the completely desugared approach — replacing the `private` directive with something like `const unique = new Name()` as has been proposed — but I don't want to paint this as a sugar/no-sugar dichotomy.)

Allen had another concern, though:
> However, a consequence of eliminating the private declaration is that we
> also eliminate the obvious way to extend object literals to support private
> properties

As I see it, that could be solved with the same #.foo syntax:

    function makeObj() {
       private unique;
       var obj = { #.unique: 42 };
       // et cetera

Another alternative, one I briefly mentioned earlier, would be to use # as a private-name equivalent of . (e.g., obj#unique instead of obj.unique). It seems like this would be a larger can of worms to open, but I mention it again in the spirit of brainstorming.

Again: private names, as a language feature, seem like a fine idea; but, while I am not at all opposed to introducing new syntax, I find the existing syntax proposal for private names would introduce alarming new complexity.


More information about the es-discuss mailing list