Security Demands Simplicity (was: Private Slots)

David Bruant bruant.d at
Sun Jan 20 04:29:33 PST 2013

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;
             this. at brand = brand;
             return this. at brand;

     class Node{
   , 'Node');

     var n = new Node();

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.


More information about the es-discuss mailing list