About private names

David Herman dherman at mozilla.com
Sun Mar 20 21:05:53 PDT 2011


> right now, bracket notation is a superset of dot notation, but it would no longer be under the proposed syntax.

I'm afraid I can't figure out what this means, but it doesn't sound true to me.

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

OK, we've heard this point a number of times at this point. I'm the original proposer of the private names strawman, so I haven't been particularly sympathetic to this critique. But it's been the reaction of several people when I've described the proposal, so it's pretty clearly worth taking seriously.

Let me try to see if I can construct examples where this might be a problem. Here's one involving a name collision:

    private draw; // for the cowboy's internal draw method
    function Cowboy(...) { ... }
    Cowboy.prototype = {
        // private method
        draw: function() { ... },
        otherMethod: function() { ... this.draw() ... },
        ...
    };
    ...
    var shape = ...;
    shape.draw(); // oops, this was supposed to be the public "draw" method

On the one hand, my feeling has been that programmers are generally in control of what they have in scope. (It isn't specified in the proposal, but I might suggest that it shouldn't be allowed to make private declarations dynamically in global scope.) But that doesn't mean that you can't still trip over it yourself, or that you could find yourself in a reasonably deep scope, and not notice that a name has been declared private.

So I guess I'm beginning to find the objections persuasive.

But when you propose *only* using the bracket notation, I think you lose something important that came with the private names proposal. The importance of the dot-notation is to distinguish the static case from the dynamic case. The dot-notation says "I know what name I'm dealing with." Now granted, the private declaration indicates a dynamic generation of a fresh name, but it still can be tied statically to the program point at which the private declaration was made.

So here's an alternative I've been kicking around lately. The private declaration is essentially as before, but we have a variation on dot-notation that is syntactically distinct from ordinary dot-notation, and can only take a private name that's in scope:

    private #draw;
    function Cowboy(...) { ... }
    Cowboy.prototype = {
        // private method
        #draw: function() { ... },
        otherMethod: function() { ... this.#draw() ... },
        ...
    };
    ...
    var shape = ...;
    shape.draw(); // this has to be the public draw method

So now you can always syntactically tell whether you're referring to a private name. You still have to know what private declaration you're getting, but you can't get confused about whether you're referring to a public vs. private name. At the same time, you still get to use dot-notation, so that you can tell that this is a case where the name's provenance is statically known.

I would still want the ability to promote a private name to its runtime value in an expression, so that you could do something like:

    friend.drawCapability = #draw;

to dynamically share a private name as needed.

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

Hm, it didn't really sound like complexity that you were objecting to, so much as the danger of confusion caused by having the dot-notation be overloaded. I don't really see the private names proposal as very complex. It seems like a fairly conservative extension of the JS object-property model in order to enable encapsulation, which is something many (not all, but many) people miss. In fact, as we've talked at Mozilla about the very real possibility of implementing portions of the DOM in JS rather than C++, we need some encapsulation mechanism with better performance than weak maps.

(Incidentally, this is all orthogonal to the separate question of whether private names should offer strong/true encapsulation. So if we can, let's avoid getting into that issue in this thread.)

Does my point about dot-notation make sense to you? What do you think of the above revision of the proposal?

Dave



More information about the es-discuss mailing list