Le 20/01/2013 06:43, Allen Wirfs-Brock a écrit :
On Jan 19, 2013, at 8:39 PM, Brendan Eich wrote:

Allen Wirfs-Brock wrote:
...

I like the fact that you used "r" as a name above because certainly a WeakMap 
can be used to define a relationship involving an immutable object o.  But we shouldn't 
be creating confusion by pretending that those relationships are the samething as a 
property of o or anyway part of o.
Quite agree.

   ...
Well, then we are probably debating about how much we agree with each other.  
Weakmaps and private Symbols are totally different things.  Just because some 
problems can be solved with either one doesn't make them equivalent.
Agreed, but the live proposal here is to use weakmaps for class private 
instance methods/variables, and not have private symbols.
Then we should be close to resolving that if we agree that WeakMap are primarily useful 
for represent external relationships between objects. The encapsulated state of an object 
isn't this sort of external relationship and presumably "private state" is the 
most intimate form of encapsulated state.  It would be very misleading to both ES 
programmer and implementors if what syntactically appears to be private state is 
specified to have the semantics of an external relationship.
I disagree with Brendan when he says "to use weakmaps for class private instance methods/variables"... well... it depends on what "use" means: The spec is allowed to /use/ anything it needs to make the class private syntax work. If the spec says that private properties are like properties but aren't enumerated in Object.gOPN calls, fine. If the spec says that private properties require a lookup to some object -> value map, fine (but misleading, I agree).

A different problem is what the private syntax is decided to expand to, which we can refer to as the "transpiler problem". Transpilers are limited to /use/ what's available in the language. While the spec can decide to invent new property types which aren't enumerated with Object.gOPN, transpilers don't have this possibility.

In my opinion, the most important topic which hasn't been addressed yet and which defines the boundaries of the 2 above points is the exact semantics of private syntax. I'm careful to not say "private properties", because it would imply that these things have the same characteristics than what we know as public properties. It's pretty clear from existing examples that we want to be able to attach values based on names, that's a given.

A couple of questions regarding class private syntax (once again, I'm only talking about the syntax, not private symbols):
1) Do we want ES5 property semantics (property descriptors, etc.)?
=> Because of the class encapsulation, I don't think enumerable, configurable, writable are needed. Public methods can guard any invariants they need.
=> No opinion yet on private getters/setters. Maybe they can be useful.
2) Do we want "private inheritance" (suggested by Brendan below)
=> No opinion yet.


But, that said, you certainly could use Weakmaps to define a style of 
relationship that supports inheritance like mention above.  Just create a 
subclass of Weakmap like:

class WeakMapWithKeyInheritance extends Weakmap {
    has(key) {
       if (super.has(key)) return true;
       let proto = Object.getPrototypeOf(key);
       If (proto === null) return false;
       return this.has(proto);
    }
    get(key) {
       if (super.has(key)) return super.get(key);
       let proto = Object.getPrototypeOf(key);
       If (proto === null) return false;
       return this.get(proto);
    }
}
Right, but could you have "classes as sugar" including private syntax as David 
proposed (based on weak maps) that can access prototype-delegated properties? (I guess 
they would be 'protected' in that case.)
Yes, its is closer to what "protected" means in some languages and we may want 
to add syntax at some point to make it easier to defined private/protected properties.  
But it would be a very misleading and unexpected if that syntax was just sugar for 
WeakMap operations.  Nobody defines private state of a class with the expectation that it 
has the implementation cost of maintaining an external relationship.
Once again, the spec (well... you in that case :-) ) will do whatever is necessary to make the feature understandable by spec readers. Transpilers will work with whatever is in the language. If they only have weakmaps, they'll use that.

I tend to be in the same camp as those who say that they only need non-private 
Symbols.  But I know that there are significant segments of the developer 
community who what stronger encapsulation than is offered by reflectable unique 
symbols.  In particular, I don't see a good way to do strong branding (which 
the DOM folks demand) using only non-private Symbols. I don't see regular 
WeakMaps as an viable solution to that problem because of the GC impact.   We 
could try to introduce a separate per instance mechanism for branding, but then 
we would have yet another orthogonal feature to integrate (including with 
Proxies) .  Private symbols, so for,  seems like smallest incremental extension 
that is a practical solution for the branding use case.
Does the branding need to be dynamic? Could the problem be solved by class private syntax?

    class Branded{
        private brand;
        constructor(brand){
            this.@brand = brand;
        }
        getBrand(){
            return this.@brand;
        }
    }

    class Node{
        constructor(brand){
            Branded.call(this, 'Node');
        }
    }

    var n = new Node();
    console.log(Branded.prototype.getBrand.call(n));

Could this work?
Once again, spec and implementations are free to see class private syntax as object own properties regardless of what we use (weakmaps?) to reason about the class syntax or to transpile it to.

David
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to