Re: Security Demands Simplicity (was: Private Slots)

2013-01-22 Thread David Bruant

Le 22/01/2013 16:02, Tom Van Cutsem a écrit :

2013/1/22 David Bruant mailto:bruan...@gmail.com>>

Le 21/01/2013 22:31, Tom Van Cutsem a écrit :

Let's talk through Allen and Brandon's suggestion of
auto-unwrapping private symbol access on proxies.
If a membrane can intercept all exchanged private symbols I
think this could be made to work.

Agreed. Unfortunately, I think the condition ("If a membrane can
intercept all exchanged private symbols") cannot be fulfilled
practically. Let's start with:

var o = {a:{a:{a:new PrivateSymbol()}}}
// send o across the membrane

The membrane has to traverse o to find the symbol. The membrane
"can" do it, but it will cost the complete traversal of all
objects being passed back and forth which has a cost. An
arbitrarily big cost for arbitrarily complex objects.


This is not my understanding of how membranes work:

- when o is passed through the membrane, a proxy |op| is created for 
it on the other side (let's call this the "inside")
- when |op.a| is accessed inside the membrane, the membrane forwards 
the operation, and creates a new proxy |opp| for the value returned by 
|o.a|.
- when |opp.a| is accessed inside the membrane, the membrane forwards 
the operation, so retrieves |o.a.a|, sees that the value is a private 
symbol, and returns a new private symbol instead.


The same argument applies to the other examples you gave: membranes 
only wrap lazily, and it's only at the point where an actual private 
symbol value is about to cross the membrane (as argument or return 
value of a forwarded operation) that one needs to detect (and wrap) 
private symbols.

True. I'm taking back what I said :-)

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


Re: Security Demands Simplicity (was: Private Slots)

2013-01-22 Thread Tom Van Cutsem
2013/1/22 David Bruant 

> Le 21/01/2013 22:31, Tom Van Cutsem a écrit :
>
>  Let's talk through Allen and Brandon's suggestion of auto-unwrapping
>> private symbol access on proxies.
>> If a membrane can intercept all exchanged private symbols I think this
>> could be made to work.
>>
> Agreed. Unfortunately, I think the condition ("If a membrane can intercept
> all exchanged private symbols") cannot be fulfilled practically. Let's
> start with:
>
> var o = {a:{a:{a:new PrivateSymbol()}}}
> // send o across the membrane
>
> The membrane has to traverse o to find the symbol. The membrane "can" do
> it, but it will cost the complete traversal of all objects being passed
> back and forth which has a cost. An arbitrarily big cost for arbitrarily
> complex objects.
>

This is not my understanding of how membranes work:

- when o is passed through the membrane, a proxy |op| is created for it on
the other side (let's call this the "inside")
- when |op.a| is accessed inside the membrane, the membrane forwards the
operation, and creates a new proxy |opp| for the value returned by |o.a|.
- when |opp.a| is accessed inside the membrane, the membrane forwards the
operation, so retrieves |o.a.a|, sees that the value is a private symbol,
and returns a new private symbol instead.

The same argument applies to the other examples you gave: membranes only
wrap lazily, and it's only at the point where an actual private symbol
value is about to cross the membrane (as argument or return value of a
forwarded operation) that one needs to detect (and wrap) private symbols.

Cheers,
Tom
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-22 Thread David Bruant

Le 21/01/2013 22:31, Tom Van Cutsem a écrit :
Let's talk through Allen and Brandon's suggestion of auto-unwrapping 
private symbol access on proxies.
If a membrane can intercept all exchanged private symbols I think this 
could be made to work.
Agreed. Unfortunately, I think the condition ("If a membrane can 
intercept all exchanged private symbols") cannot be fulfilled 
practically. Let's start with:


var o = {a:{a:{a:new PrivateSymbol()}}}
// send o across the membrane

The membrane has to traverse o to find the symbol. The membrane "can" do 
it, but it will cost the complete traversal of all objects being passed 
back and forth which has a cost. An arbitrarily big cost for arbitrarily 
complex objects.


I could stop the argument here, but for the fun of it, I'll go further :-)

function PasswordProtectedSymbol(symbol, password){
return new Proxy({}, {
get: function(target, name){
if(name === password)
return symbol;
}
})
}

If such an object is crosses a membrane, the membrane needs to know the 
password to find the encapsulated symbol. The membrane "can" know the 
password from previous communication between untrusted parties, but it 
requires to know that such string was the password (note that the 
property name is not on the target, so Object.gOPN cannot help the 
membrane). Things can get trickier if the password is partially computed 
in both sides. For the membrane to know the password, it requires the 
membrane author to read and understand the code of both untrusted 
parties in order to understand the semantics of the communication 
between the 2 parties. This is very expensive and error prone.


Let's see another pattern. As an intermediate state in the 
demonstration, consider the following InfiniteObject abstraction:


var infiniteHandler = {
get: function(){
return new InfiniteObject();
}
}
var target = {};

function InfiniteObject(){
return new Proxy(target, infiniteHandler)
}

var do = new InfiniteObject();
do.you.think.this.can.ever.end ? 'nope' : 'yep';

A slightly different implementation could accept all 1-char strings (why 
not even putting them in the target) and decide that the proxy-chain 
stops to provide a private symbol if you pass in a password as in 
"obj.p.a.s.s.w.o.r.d". In this case, fully traversing the object means 
doing an infinite loop and the above point about passwords and membrane 
being aware of communication semantics still stands.


The membrane can always capture the private symbols I think, but it may 
come at an unpractical price.



hmm... For all the above tricks to work, it requires that the untrusted 
parties can create their own functions that the membrane is unaware of. 
Maybe it could be considered to add a Loader option so that syntax-based 
initializations ({}, [], function(){}...) trigger a custom constructor 
in loaded code (only in loaded code, not globally of course). This 
custom constructor would make *all* new objects


If loaders don't have such an option, it's possible to parse the code 
and wrap all initializations. I have written such a tool recently for a 
completely unrelated purpose [1]. It's a ugly AST hack, please forgive 
the naivety of the implementation. Also the translated code does not 
have exactly the same semantics than the source one for hoisting reasons 
and a couple of other edge cases but I chose not to care in my case as a 
first approximation.


I have no idea if the perf cost would be more practical for either the 
loader or the rewriting solution. It seems worth investigating though.


David

[1] 
https://github.com/DavidBruant/HarmonyProxyLab/blob/ES3AndProxy/ES3AndProxy/tests/tools/Test262Converter/transform.js

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


Re: Security Demands Simplicity (was: Private Slots)

2013-01-21 Thread Allen Wirfs-Brock
(This message seems like a reasonable place  to jump back into this thread.  
But, I'm not particularly picking on Tom here...)


On Jan 21, 2013, at 1:31 PM, Tom Van Cutsem wrote:

> 2013/1/21 Kevin Smith 
> 
> 
> A root  problem is that on method invocations through a proxy methods of the 
> target object are invoked with the proxy, rather than the target, as the this 
> value.  This means that any assumption the methods have about valid this 
> values are broken.
> 
I'll +1 myself here.

> I believe this is correct.  It is a separate proxy issue not directly related 
> to WeakMap/private symbol debate.
> 
Actually, I think it is closely related.  Private state state access (and 
branding) mechanism don't work if you don't have the right this value or if the 
private state access doesn't automatically forward through through a proxy this 
to the target this.. 

> Indeed. But in Javascript, methods shouldn't (in general) make any 
> assumptions about their |this| values. The |this| value can be any random 
> object. It's just the zeroth parameter to a function. That's why in traits.js 
> (which was designed for high-integrity abstractions) we decided to .bind() 
> all methods so the |this| value could be relied upon.

I understand and largely agree with the spirit of this comment, but in fact 
Javascript methods make all sort of assumptions about their this value.  Every 
time you invoke a method property or access a state property through this you 
are making assumptions. Every time you check the identify of this you are 
making assumptions.  Every time you pass this to another function you are 
making assumptions.  Many times the assumptions aren't verified (and I think 
that is typically a good design choice) but if they are violated, the program 
will misbehave.

Sometimes, methods preflight check that the this value is the "right kind" of 
object.  Many of the built-in methods do this, presumably so they can take 
advantage of optimized native layout.  If those checks aren't made an 
implementation could have memory corruption bugs.

Passing the proxy rather than the target as the this value creates problems 
because the mechanism that are used to verify the assumptions or or the 
assumptions thenselves depend upon either object identify (for example looking 
up the this value in a WeakMap based brand registry) or direct access to target 
object state (most of the built-ins).

The current Proxy design side-steps these issues in some special cases. For 
example [[Prototype]] access is a special MOP call that always reaches into the 
target. But, as far as I can tell there isn't a general solution to this 
problem in the current Proxy design.  Certainly it isn't clear how the 
built-ins are supposed to be specified so that they work when handed a proxy as 
their this value. 

We can probably fix the built-ins with some ad hoc language about them 
automatically resolving proxies to the target as the this value. Or perhaps we 
could expand the internal MOP api  to include a resolve proxy to target 
operation.  

Using private symbols for all of these cases, including the built-ins also 
seems like an alternative that may work. 

Allen



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


Re: Security Demands Simplicity (was: Private Slots)

2013-01-21 Thread Allen Wirfs-Brock

On Jan 21, 2013, at 4:44 PM, Nathan Wall wrote:

>> Object.create(new Date).getDate(); // works but is specified to not work 
> 
> I understand why this doesn't work, but why *shouldn't* it work? I'm curious 
> why the language doesn't allow for this... ? It seems reasonable at first 
> glance.


Because, the "Dateness" of an object is an characteristic of an instance not of 
what is on its inheritance  chain. 

In ES <= 5.1 this is defined in terms of the [[Class]] internal property which 
identifies the specific low level built-in form of an object.  You might think 
about it as defining the private record structure of an instance and other  
specific per instance characteristics such as which internal methods are 
applicable to the instance.

Changing the prototype (via __proto__) doesn't change the shape of the instance 
or modify its [[Class]].  That aspect (which at an implementation level, might 
impact what is actually allocated) is immutably set for each instance when it 
is allocated.  This is why the built-ins including Array in ES <=5.1 are not 
"subclassable".

In the the last couple ES6 specs drafts  there is a mechanism  defined in terms 
of @@create methods that allow subclasses to inherit such specialized instance 
allocation procedures.  This allows subclasses instance of  Array, Date, and 
other built-in to be fully functional with all the inherited built-in methods.

An ES programmer could directly invoked Date[@@alloc] like:

let newInst = Date[@@alloc]]();  //allocate a new data-like instance
Date.call(newInst);  //initialize the private date state and make the instance 
as initalized
newInst.__proto__= Object.create(Date.prototype)  //give it a new prototype 
that inherits from Data.prototype

but its much easier to just say:

let newInst = new class extends Date{};

which does pretty much the same thing.

Allen

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


RE: Security Demands Simplicity (was: Private Slots)

2013-01-21 Thread Nathan Wall
> Object.create(new Date).getDate(); // works but is specified to not work 

I understand why this doesn't work, but why *shouldn't* it work? I'm curious 
why the language doesn't allow for this... ? It seems reasonable at first 
glance.

Nathan
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-21 Thread Tom Van Cutsem
2013/1/21 Kevin Smith 

>
>
> A root  problem is that on method invocations through a proxy methods of
>> the target object are invoked with the proxy, rather than the target, as
>> the this value.  This means that any assumption the methods have about
>> valid this values are broken.
>>
>
> I believe this is correct.  It is a separate proxy issue not directly
> related to WeakMap/private symbol debate.
>

Indeed. But in Javascript, methods shouldn't (in general) make any
assumptions about their |this| values. The |this| value can be any random
object. It's just the zeroth parameter to a function. That's why in
traits.js (which was designed for high-integrity abstractions) we decided
to .bind() all methods so the |this| value could be relied upon.

Let's talk through Allen and Brandon's suggestion of auto-unwrapping
private symbol access on proxies.
If a membrane can intercept all exchanged private symbols I think this
could be made to work.

Cheers,
Tom
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-21 Thread Tom Van Cutsem
2013/1/21 Brendan Eich 

> Andreas Rossberg wrote:
>
>
>> On 21 Jan 2013 17:33, "Tom Van Cutsem" > tomvc...@gmail.com>> wrote:
>> >
>> > So let's revisit the assumption: if a membrane does intercept and wrap
>> symbols, then two previously isolated pieces of code can never come to
>> share the same private symbol.
>>
>> I'm not sure I understand what "wrapping a symbol" would actually mean.
>> Are you implying that proxies that target a symbol should actually be
>> usable _as_ a symbol?
>>
>>  I think Tom meant wrapping as in membrane-wrapping, just as any object
> going through a membrane implemented by a proxy would be wrapped. I.e.,
> symbols are not primitive values, they are objects. So membrane-wrapping a
> symbol means making a new symbol that can be mapped back to the original
> when flowing back across the membrane.
>
> We had the old .public idea in play to do something like this. A proxy
> would never get access to a private symbol, only its "public key". If it
> had been endowed with a map of such back to the private identities, then it
> could unwrap. Otherwise, no privacy leak.
>
> It seems even simpler to make symbols a distinct class of object (special
> case for property naming) and otherwise let them be membrane-wrapped.
> (Let's defer typeof result value.)


What I meant is that the membrane allocates a new private symbol per
private symbol it intercepts, and keeps a mapping between the two. I didn't
mean to imply creating a proxy for a symbol.

Cheers,
Tom
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-21 Thread Brendan Eich

Kevin Smith wrote:



A root  problem is that on method invocations through a proxy
methods of the target object are invoked with the proxy, rather
than the target, as the this value.  This means that any
assumption the methods have about valid this values are broken.


I believe this is correct.  It is a separate proxy issue not directly 
related to WeakMap/private symbol debate.


That's right. It is not identital too, or completely overlapping with, 
the private member access that comes up with the other proposals -- not 
all such accesses involve |this|.


Note also that in the browser JS embedding, it is crucial that |this| 
bind to the WindowProxy, not the Window (the object at the top of the 
scope chain). FWIW, and we do hope to keep ES6 Proxy and WindowProxy 
aligned so that implementations could use the former (via internal C++ 
APIs at first, no doubt) to implement the latter.


/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-21 Thread Kevin Smith
A root  problem is that on method invocations through a proxy methods of
> the target object are invoked with the proxy, rather than the target, as
> the this value.  This means that any assumption the methods have about
> valid this values are broken.
>

I believe this is correct.  It is a separate proxy issue not directly
related to WeakMap/private symbol debate.

{ Kevin }
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-21 Thread Allen Wirfs-Brock

On Jan 21, 2013, at 12:04 AM, David Bruant wrote:

> Le 21/01/2013 03:35, Allen Wirfs-Brock a écrit :
>> 
> 
>> Also, I think some of the issues discussed in the thread 
>> https://mail.mozilla.org/pipermail/es-discuss/2012-December/027246.html have 
>> bearing on this discussion.  It is probably worth taking a second look.
> I think too that this thread revealed unclear stratification properties in 
> built-in algorithms, but I'm not following how relates to this discussion.
> 

In particular, look at the above threading starting here 
https://mail.mozilla.org/pipermail/es-discuss/2012-December/027277.html .  For 
internal method calls, the default behavior of Proxy is to forward to the 
target.  But for ES level method calls through the Proxy,  delegation is used. 
This can leads to inconsistent behavior between direct use of a target object 
and proxied use of that target, even if the proxy has no handler behavior.  

A root  problem is that on method invocations through a proxy methods of the 
target object are invoked with the proxy, rather than the target, as the this 
value.  This means that any assumption the methods have about valid this values 
are broken. For example, if a built-in method requires a specific 
implementation level record structure, that method will fail unless it 
explicitly deals with the possibility it might be indirected through multiple 
proxies.

This is why we have the private symbol proxy issues we have been discussing.  
Such a method, instead of directly accessing private symbol properties on on 
the instance it is operating upon is forced to re-delegate each access back 
through the proxy.

This also creates problems is you were using WeakMaps to represent encapsulated 
state:

import $$create ...  ;   //get the @@create symbol
let fooPrivate = new WeakMap;
export class Foo {
   doSomething)_ {
   let privateState = fooPrivate.get(this)
   if (privateState == undefined) throw Error("invalid foo object");
   /* do something using the private state */
}
} 
Object.mixin({
[$$create] () {
 let obj = super[$$create]();  //allocate an ordinary instance
 fooPrivate.set(obj, {});  //set up a private slot for the new object
 return obj
}
});


let f = new Foo();
let pf = new Proxy(f, {});

f.doSomething();  //works fine
pf.doSomething();  //throws because pf is passed as the this value to 
doSomething and pf does not have an entry in fooPrivate.


Allen

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


Re: Security Demands Simplicity (was: Private Slots)

2013-01-21 Thread Brendan Eich

Andreas Rossberg wrote:


On 21 Jan 2013 17:33, "Tom Van Cutsem" > wrote:

>
> So let's revisit the assumption: if a membrane does intercept and 
wrap symbols, then two previously isolated pieces of code can never 
come to share the same private symbol.


I'm not sure I understand what "wrapping a symbol" would actually 
mean. Are you implying that proxies that target a symbol should 
actually be usable _as_ a symbol?


I think Tom meant wrapping as in membrane-wrapping, just as any object 
going through a membrane implemented by a proxy would be wrapped. I.e., 
symbols are not primitive values, they are objects. So membrane-wrapping 
a symbol means making a new symbol that can be mapped back to the 
original when flowing back across the membrane.


We had the old .public idea in play to do something like this. A proxy 
would never get access to a private symbol, only its "public key". If it 
had been endowed with a map of such back to the private identities, then 
it could unwrap. Otherwise, no privacy leak.


It seems even simpler to make symbols a distinct class of object 
(special case for property naming) and otherwise let them be 
membrane-wrapped. (Let's defer typeof result value.)


/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-21 Thread David Bruant

Le 21/01/2013 19:20, Andreas Rossberg a écrit :


On 21 Jan 2013 17:33, "Tom Van Cutsem" > wrote:

>
> So let's revisit the assumption: if a membrane does intercept and 
wrap symbols, then two previously isolated pieces of code can never 
come to share the same private symbol.


I'm not sure I understand what "wrapping a symbol" would actually 
mean. Are you implying that proxies that target a symbol should 
actually be usable _as_ a symbol?


Maybe that's what Tom meant, but in the case he described, creating a 
corresponding new private symbol would work just fine without having to 
create a proxy around a private symbol.


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


Re: Security Demands Simplicity (was: Private Slots)

2013-01-21 Thread Andreas Rossberg
On 21 Jan 2013 17:33, "Tom Van Cutsem"  wrote:
>
> So let's revisit the assumption: if a membrane does intercept and wrap
symbols, then two previously isolated pieces of code can never come to
share the same private symbol.

I'm not sure I understand what "wrapping a symbol" would actually mean. Are
you implying that proxies that target a symbol should actually be usable
_as_ a symbol?

/Andreas
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-21 Thread Andreas Rossberg
Amen.

/Andreas

On 21 Jan 2013 17:23, "Tom Van Cutsem"  wrote:
>
> 2013/1/20 Allen Wirfs-Brock 
>>
>> I don't have a problem at all with making the proxy story more
complicated.  Proxys are an expert feature designed for some specific use
cases.  they are probably an attractive nuisance.  I would advise most JS
programmer that if they are going down the road of using a Proxy, they are
probably making a mistake.  In that light,  placing the extra complexity
within the Proxy story seems just fine.
>
>
> While in the specific case of proxies & private symbols, I think it is
fine if proxies take an extra complexity hit, I'd like to push back a
little here regarding the more general point.
>
> People often complain that proxies are complicated. Well here's the deal:
proxies are only as complicated as the ES object model requires them to be.
The more features we add to the ES object model, the more complexity we
face in proxies. It's awkward to blame proxies for that extra complexity.
Proxies are just a (power-)tool that aim to let the ES programmer emulate
all aspects of ES objects in Javascript itself. If Javascript objects
become more complex, they obviously also become more complex to emulate.
>
> It also gives a false sense of simplicity to think that pushing off extra
complexity into proxies actually sweeps all the complexity under the rug
for the non-expert programmers. Extra complexity in proxies also implies
extra complexity for any other kind of exotic/host object. Point-in-case:
how will host objects interact with private symbols? It isn't entirely
obvious. Does a WindowProxy forward them, or does each WindowProxy have its
own set? These issues reappear outside of Proxies proper.
>
> Cheers,
> Tom
>
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-21 Thread Tom Van Cutsem
2013/1/21 Brandon Benvie 

>
> On Sun, Jan 20, 2013 at 10:41 PM, Brendan Eich wrote:
>
>> Brandon Benvie wrote:
>>
>>> Going to the title of this thread, it's my view that private symbols
>>> should just auto-forward to the ultimate target no matter what,
>>>
>>
>> Doesn't this allow private symbols to pierce membranes? Or do you mean
>> that each trap would have to check a whitelist and throw on miss.
>>
>>
> Somebody argued a while back, which convinced me, was that if the two
> parties already have access to the same private symbol, then they've
> already got a communication channel most likely. I would argue further that
> a private symbol's primary use case is for holding sensitive internal state
> that absolutely shouldn't be mucked with in most cases. If you wanted it to
> be potentially mucked with, you'd make it a normal symbol.
>

As David mentioned already, I have previously argued that symbols should
pass through a membrane unwrapped (like primitive values) because the only
useful property of a symbol is its identity, and wrapping an identity with
a fresh identity is pointless.

Given that assumption ("symbols pierce membranes"), Allen and Brandon's
proposal of having private symbol access auto-unwrap proxies is a
non-starter, as David already explained (it would open up a communications
channel).


So let's revisit the assumption: if a membrane does intercept and wrap
symbols, then two previously isolated pieces of code can never come to
share the same private symbol. In this case, Allen and Brandon's proposal
might actually work out, in which case we avoid proxy vs private symbol
complexity, and wrapping class instances with private state just works.

If membranes use WeakMaps internally to ensure that they always generate
unique wrappers for their objects, then wrapping private symbols might just
work (because passing the same private symbol back and forth across the
membrane will preserve the symbol's identity).

The remaining assumption is that there are no built-in, well-known private
symbols in the global environment by default. I.e. all "well known" symbols
such as @@iterator should be unique symbols. Otherwise it's trivial for two
isolated scripts to get access to the same private symbol, and pierce the
membrane that separates them.

Cheers,
Tom
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-21 Thread Tom Van Cutsem
2013/1/20 Allen Wirfs-Brock 

> I don't have a problem at all with making the proxy story more
> complicated.  Proxys are an expert feature designed for some specific use
> cases.  they are probably an attractive nuisance.  I would advise most JS
> programmer that if they are going down the road of using a Proxy, they are
> probably making a mistake.  In that light,  placing the extra complexity
> within the Proxy story seems just fine.
>

While in the specific case of proxies & private symbols, I think it is fine
if proxies take an extra complexity hit, I'd like to push back a little
here regarding the more general point.

People often complain that proxies are complicated. Well here's the deal:
proxies are only as complicated as the ES object model requires them to be.
The more features we add to the ES object model, the more complexity we
face in proxies. It's awkward to blame proxies for that extra complexity.
Proxies are just a (power-)tool that aim to let the ES programmer emulate
all aspects of ES objects in Javascript itself. If Javascript objects
become more complex, they obviously also become more complex to emulate.

It also gives a false sense of simplicity to think that pushing off extra
complexity into proxies actually sweeps all the complexity under the rug
for the non-expert programmers. Extra complexity in proxies also implies
extra complexity for any other kind of exotic/host object. Point-in-case:
how will host objects interact with private symbols? It isn't entirely
obvious. Does a WindowProxy forward them, or does each WindowProxy have its
own set? These issues reappear outside of Proxies proper.

Cheers,
Tom
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-21 Thread Tom Van Cutsem
2013/1/20 Kevin Smith 

>
>  It is not. At the exit of the get trap, the JS engine checks whether
>> invariants should be enforced for the given property on the target. In your
>> case, the runtime sees that the target has a non-configurable non-writable
>> property called 'foo' with 1 as value. When you try to return 0, it will
>> throw a TypeError because of invariant violation. You can read about
>> invariants at
>> http://wiki.ecmascript.org/doku.php?id=harmony:direct_proxies#invariant_enforcement
>>
>>
> Excellent - thanks for the link!
>

I wrote an introductory article a while back explaining precisely the
interaction between frozen objects and proxies, and the invariant checks.
Easier to digest than the draft spec on the wiki:
http://soft.vub.ac.be/~tvcutsem/invokedynamic/frozen-proxies

Cheers,
Tom
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-21 Thread David Bruant

Le 21/01/2013 03:35, Allen Wirfs-Brock a écrit :


On Jan 20, 2013, at 5:42 PM, David Bruant wrote:


Le 20/01/2013 23:05, Allen Wirfs-Brock a écrit :



On Jan 20, 2013, at 11:12 AM, David Bruant wrote:
"complicated" was an expression. Either proxies don't work with 
class instances, making them vastly pointless or classes need to 
publicize their private symbols (or maybe expose something like 
"myClass.acceptProxy" which is marginally better), thus ruining 
their own encapsulation.
Actually this whole discussion makes me question the validity of the 
current Proxy design rather than that of private Symbol.  I may be 
on the road towards getting on the NotificationProxy train.
If there is time to make that big of a change, Mark's idea of action 
proxies could be considered too. I've only expressed reluctance on 
the list, because it allows to do weird things when badly used, but 
for all use cases I've had, it would be fine. Tom expressed 
reluctance regarding the cost of action proxies, but I'm not entirely 
sure it's founded.
Although Notification and action proxies are good to get rid of the 
invariants cost, I'm not entirely sure they can help to reduce the 
complexity when it comes to private symbols.




(...)

This suggests a possible generalized solution to the Proxy/private 
symbol exposure problem:


The [[Get]] and [[Set]]  (and probably some others) internal methods 
of a proxy never call the corresponding trap when the property key 
is a private Symbol.  Instead, they trace the [[Target]] chain of 
the proxy until a non-proxy object is reached (call this the 
"ultimate target").  It then invokes the ultimate target's 
[[Gett]]/[[Set]] using that same private Symbol key.  The result of 
that operation is then returned as the value of the original 
[[Get]]/[[Set]].


The "private" state access is applied to the correct object and 
there is no exposure of the private symbol!
It can work for built-in private state (and could work for private 
class syntax too), but not for user-generated or obtained private 
symbols:
Let's say 2 untrusted parties are in 2 membranes. They share a 
private symbol and each has access to a proxy wrapping a common 
target. With the private symbols semantics you're describing, these 2 
untrusted parties have an unmediated communication channel.


How did they originally come to share the private symbol?  Don't they 
have to have some common point of origin with visibility of the symbol 
or have both been provided the private symbol by some third party.
No, they have shared the symbol through mediated communication. As Tom 
has argued multiple times, while symbols are "objects", they should be 
considered as primitive values that can't be wrapped by proxies.
So the 2 parties, while using the mediated communication came to share a 
private symbol. They didn't need a third party for that.


In either case couldn't they have closure captured references to each 
other and use those references for direct communicate?
No, you created each of this context separately and you are the only 
entity with access to both and for whatever good reason of yours, you 
initially make them share a single object through which their mediated 
communication start. A setup like one that Mark describes much better 
than I do [1].
For instance, you're a webpage, each untrusted party is a widget and you 
have an event mechanism through which you allow widgets to communicate 
for some time and for whatever good reason.


An unmediated communication channel defeats the purpose of having put 
the 2 untrusted parties in membranes in the first place.
The semantics of user-generated or obtained symbols has to go through 
proxy mediation because of this use case, hence the whitelist and the 
unknownPrivateSymbol trap in the current proxy design.


This really makes me start to question even more the viability of 
Proxy based membranes (direct proxies, at least) as an isolation 
mechanism. Independent of private Symbols,  it isn't clear that it is 
a practical approach.
I wonder how you're coming to such a question. It is a practical 
approach assuming proxies can properly mediate communication.


Also, I think some of the issues discussed in the thread 
https://mail.mozilla.org/pipermail/es-discuss/2012-December/027246.html have 
bearing on this discussion.  It is probably worth taking a second look.
I think too that this thread revealed unclear stratification properties 
in built-in algorithms, but I'm not following how relates to this 
discussion.


David

[1] 
http://www.youtube.com/watch?v=w9hHHvhZ_HY&feature=player_detailpage#t=2574s 

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


Re: Security Demands Simplicity (was: Private Slots)

2013-01-20 Thread Brandon Benvie
Er to clarify, I didn't mean non-proxied. I meant directly forwarded to the
target with no possibility of a malfunction or interception by any proxy
traps. I want the property forwarded unconditionally, so it has the same
guarantees that a regular [[Get]] does (except in the case of revokable
proxies which will have to throw when the target is gone, but this still
implies that the ultimate target object can't be harmed by the proxy
improperly handling the forward/throwing).


On Sun, Jan 20, 2013 at 11:23 PM, Brandon Benvie
wrote:

>
>
>
> On Sun, Jan 20, 2013 at 10:41 PM, Brendan Eich wrote:
>
>> Brandon Benvie wrote:
>>
>>> Going to the title of this thread, it's my view that private symbols
>>> should just auto-forward to the ultimate target no matter what,
>>>
>>
>> Doesn't this allow private symbols to pierce membranes? Or do you mean
>> that each trap would have to check a whitelist and throw on miss.
>>
>>
> Somebody argued a while back, which convinced me, was that if the two
> parties already have access to the same private symbol, then they've
> already got a communication channel most likely. I would argue further that
> a private symbol's primary use case is for holding sensitive internal state
> that absolutely shouldn't be mucked with in most cases. If you wanted it to
> be potentially mucked with, you'd make it a normal symbol.
>
>
>>  and that this "trap opt-out" on a per property basis should be counted
>>> as a feature instead of a limitation.
>>>
>>
>> I don't know what you mean by this clause.
>
>
> What I meant was that it'd be a useful feature to have a method of
> selectively making properties non-proxied. For example, say Date was
> implemented using the @@DateValue private symbol. As the implementor of
> Date, I'd have no problem with Date instances being proxied, but I'd want
> to continue having guarantees about just that one property. I'd want
> guarantees that it will *not* throw unexpectedly and leave my object (the
> actual proxy target) in a broken state. I think it'd be really useful to
> have this guarantee as a feature of private symbols (with the other benefit
> that it drastically simplifies the proxy/private.symbol story).
>
>
>> /be
>>
>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-20 Thread Brandon Benvie
On Sun, Jan 20, 2013 at 10:41 PM, Brendan Eich  wrote:

> Brandon Benvie wrote:
>
>> Going to the title of this thread, it's my view that private symbols
>> should just auto-forward to the ultimate target no matter what,
>>
>
> Doesn't this allow private symbols to pierce membranes? Or do you mean
> that each trap would have to check a whitelist and throw on miss.
>
>
Somebody argued a while back, which convinced me, was that if the two
parties already have access to the same private symbol, then they've
already got a communication channel most likely. I would argue further that
a private symbol's primary use case is for holding sensitive internal state
that absolutely shouldn't be mucked with in most cases. If you wanted it to
be potentially mucked with, you'd make it a normal symbol.


>  and that this "trap opt-out" on a per property basis should be counted as
>> a feature instead of a limitation.
>>
>
> I don't know what you mean by this clause.


What I meant was that it'd be a useful feature to have a method of
selectively making properties non-proxied. For example, say Date was
implemented using the @@DateValue private symbol. As the implementor of
Date, I'd have no problem with Date instances being proxied, but I'd want
to continue having guarantees about just that one property. I'd want
guarantees that it will *not* throw unexpectedly and leave my object (the
actual proxy target) in a broken state. I think it'd be really useful to
have this guarantee as a feature of private symbols (with the other benefit
that it drastically simplifies the proxy/private.symbol story).


> /be
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-20 Thread Brendan Eich

Brandon Benvie wrote:
Going to the title of this thread, it's my view that private symbols 
should just auto-forward to the ultimate target no matter what,


Doesn't this allow private symbols to pierce membranes? Or do you mean 
that each trap would have to check a whitelist and throw on miss.


and that this "trap opt-out" on a per property basis should be counted 
as a feature instead of a limitation.


I don't know what you mean by this clause.

/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-20 Thread Brandon Benvie
Going to the title of this thread, it's my view that private symbols should
just auto-forward to the ultimate target no matter what, and that this
"trap opt-out" on a per property basis should be counted as a feature
instead of a limitation. Making any class/construct automatically
unproxyable upon its first use of a private symbol, as someone said
earlier, fatally wounds the value of proxies. But the more complex
solutions are hacky, as Brendan put it, at best and flimsy/fragile in all
likelihood, The only other viable option is to remove private symbols
entirely or to simply expose them to proxy traps, essentially making them
slightly-less-visible-but-not-entirely-private symbols.


On Sun, Jan 20, 2013 at 9:39 PM, Brendan Eich  wrote:

> Allen Wirfs-Brock wrote:
>
>> This really makes me start to question even more the viability of Proxy
>> based membranes (direct proxies, at least) as an isolation mechanism.
>> Independent of private Symbols,  it isn't clear that it is a practical
>> approach.
>>
>
> Firefox relies on proxies based on the original spec. They are "viable" --
> we don't have any soundness problems, and we bugfix validity problems until
> zarro boogs.
>
> Of course, we have not yet implemented symbols, private or public.
>
> Seriously, why are you doubting proxies? Please give more of an analytical
> argument. Yes, unknownPrivateSymbol as a "throw or do nothing" trap seems
> hacky. We may find a better way. But that's not a problem with proxies or
> membranes so much as private symbols in conjunction with the MOP and the
> integrity properties we want to enforce.
>
> /be
>
> __**_
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/**listinfo/es-discuss
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-20 Thread Brendan Eich

Allen Wirfs-Brock wrote:
This really makes me start to question even more the viability of 
Proxy based membranes (direct proxies, at least) as an isolation 
mechanism. Independent of private Symbols,  it isn't clear that it is 
a practical approach.


Firefox relies on proxies based on the original spec. They are "viable" 
-- we don't have any soundness problems, and we bugfix validity problems 
until zarro boogs.


Of course, we have not yet implemented symbols, private or public.

Seriously, why are you doubting proxies? Please give more of an 
analytical argument. Yes, unknownPrivateSymbol as a "throw or do 
nothing" trap seems hacky. We may find a better way. But that's not a 
problem with proxies or membranes so much as private symbols in 
conjunction with the MOP and the integrity properties we want to enforce.


/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-20 Thread Brandon Benvie
This looks to address the issues. The reason Proxoes would work (it doesn't
currently because I opted to switch back to using a regular internal
property because of the issue I mentioned) is because getting the date
value changes from "get internal property value" for which Proxies have no
specified forwarding method, to "forward [[Get]] of @@DateValue" which
obviously they have the mechanism to accomplish.

On Sunday, January 20, 2013, Allen Wirfs-Brock wrote:

>
> On Jan 20, 2013, at 4:42 PM, Brandon Benvie wrote:
>
> On Sunday, January 20, 2013, Allen Wirfs-Brock wrote:
>>
>> I'm not sure if you are getting at something other than what I've
>> described above.  If a @@DateValue private symbol is actually used as the
>> implementation of [[DateValue]] then actuality that would happen.
>>
>
> I explored implementing [[DateValue]], [[NumberValue]], etc. as symbols
> e.g. @@DateValue, but this causes observably different behavior from what
> is specified with a.) inheritance, and b.) interaction with proxies.
>
>
> I spend a lot of time working of Date last week, so you don't have the
> latests.
>
> In the case of inheritance at least, if it has observably different
> behavior it hasn't been implemented correctly or the spec. is still buggy.
>
> This is what my working draft currently says:
>
> Unless explicitly stated otherwise, the methods of the Date prototype
> object defined below are not generic and the *this* value passed to them
> must be an object that has a [[DateValue]] internal data property that has
> been initialized to a time value.
>
> The abstract operation thisTimeValue(*value*) performs the following
> steps:
>
>1. If Type(*value)* is Object and *value* has a [[DateValue]] internal
>data property, then
>   1. Let *n* be the Number that is the value of *value’s*[[NumberData]] 
> internal data property.
>   2. If *n* is not *undefined*, then return *n*.
>2. Throw a *TypeError* exception.
>
> In following descriptions of functions that are properties of the Date
> prototype object, the phrase “this Date object” refers to the object that
> is the *this* value for the invocation of the function. The phrase “this
> time value” within the specification of a method refers to the result
> returned  by calling the abstract operation thisTimeValue with the 
> *this*value of the method invocation passed as the argument.
>
>
> Object.create(new Date).getDate(); // works but is specified to not
> work
>
>
> If you are using a private Symbol for [[DateValue]] then the "has a
> [[DateValue]] internal data property" check in the above code needs to do a
> [[HasOwnProperty]] check rather than a [[HasProperty]]
>
>
> new Proxy(new Date, {}).getDate(); // works but is specified to not
> work
>
>
> Not sure why this works in you implementation.  Can you explain.
>
>
> Since Proxy is new in ES6 this of course can still be fixed, but to make
> the first case work would be a (probably benign) backward incompatible
> change and isn't going to work cross-engine unless the spec is changed to
> explicitly allow/require it.
>
>
> Right, everything is still in flux which is why it is great that you are
> trying these things.
>
> Allen
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-20 Thread Allen Wirfs-Brock

On Jan 20, 2013, at 5:42 PM, David Bruant wrote:

> Le 20/01/2013 23:05, Allen Wirfs-Brock a écrit :
> 
> 
>> On Jan 20, 2013, at 11:12 AM, David Bruant wrote:
>>> "complicated" was an expression. Either proxies don't work with class 
>>> instances, making them vastly pointless or classes need to publicize their 
>>> private symbols (or maybe expose something like "myClass.acceptProxy" which 
>>> is marginally better), thus ruining their own encapsulation.
>> Actually this whole discussion makes me question the validity of the current 
>> Proxy design rather than that of private Symbol.  I may be on the road 
>> towards getting on the NotificationProxy train.
> If there is time to make that big of a change, Mark's idea of action proxies 
> could be considered too. I've only expressed reluctance on the list, because 
> it allows to do weird things when badly used, but for all use cases I've had, 
> it would be fine. Tom expressed reluctance regarding the cost of action 
> proxies, but I'm not entirely sure it's founded.
> Although Notification and action proxies are good to get rid of the 
> invariants cost, I'm not entirely sure they can help to reduce the complexity 
> when it comes to private symbols.
> 
> 
>> (...)
>> 
>> This suggests a possible generalized solution to the Proxy/private symbol 
>> exposure problem:
>> 
>> The [[Get]] and [[Set]]  (and probably some others) internal methods of a 
>> proxy never call the corresponding trap when the property key is a private 
>> Symbol.  Instead, they trace the [[Target]] chain of the proxy until a 
>> non-proxy object is reached (call this the "ultimate target").  It then 
>> invokes the ultimate target's [[Gett]]/[[Set]] using that same private 
>> Symbol key.  The result of that operation is then returned as the value of 
>> the original [[Get]]/[[Set]].
>> 
>> The "private" state access is applied to the correct object and there is no 
>> exposure of the private symbol!
> It can work for built-in private state (and could work for private class 
> syntax too), but not for user-generated or obtained private symbols:
> Let's say 2 untrusted parties are in 2 membranes. They share a private symbol 
> and each has access to a proxy wrapping a common target. With the private 
> symbols semantics you're describing, these 2 untrusted parties have an 
> unmediated communication channel.

How did they originally come to share the private symbol?  Don't they have to 
have some common point of origin with visibility of the symbol or have both 
been provided the private symbol by some third party.  In either case couldn't 
they have closure captured references to each other and use those references 
for direct communicate?


> An unmediated communication channel defeats the purpose of having put the 2 
> untrusted parties in membranes in the first place.
> The semantics of user-generated or obtained symbols has to go through proxy 
> mediation because of this use case, hence the whitelist and the 
> unknownPrivateSymbol trap in the current proxy design.

This really makes me start to question even more the viability of Proxy based 
membranes (direct proxies, at least) as an isolation mechanism. Independent of 
private Symbols,  it isn't clear that it is a practical approach. 

Also, I think some of the issues discussed in the thread 
https://mail.mozilla.org/pipermail/es-discuss/2012-December/027246.html have 
bearing on this discussion.  It is probably worth taking a second look.

Allen

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


Re: Security Demands Simplicity (was: Private Slots)

2013-01-20 Thread Brendan Eich

David Bruant wrote:

Le 20/01/2013 21:53, Brendan Eich a écrit :

Allen Wirfs-Brock wrote:
We we were going to talk about adding support for addition semantics 
to  classes we should start at the level of the object model.  Not 
with syntax. ES6 class syntax is good because it is defined in terms 
of the object model and more basic operations that are defined in 
the language.  You don't have to use class syntax to define a class 
equivalent. So, if we are going to introduce private object state 
the first step is to define how it works at the object model level.


Cutting there to dodge the controversy over private-in-class based on 
weak maps, to divide and conquer in the meta-discussion with David.


Here I agree with you, and we have talked in the past of the perils 
of "Scenario Solving" by adding just-so syntax with novel semantics, 
which is not decomposed into orthogonal primitives. You saw that in a 
past life (VB5, cough) and it made messes, even though the intentions 
(serving developer problem-scenarios) were good.
I'm too new to the programming language world, so I don't have this 
context, but I'm curious. Do you have links or further explanations on 
this topic?


Take the Scheme Report intro paragraph, for example:

"Programming languages should be designed not by piling feature on top 
of feature, but by removing the weaknesses and restrictions that make 
additional features appear necessary. Scheme demonstrates that a very 
small number of rules for forming expressions, with no restrictions on 
how they are composed, suffice to form a practical and efficient 
programming language that is flexible enough to support most of the 
major programming paradigms in use today. "


Contrast with a language such as VB in the context of MS COM:

http://www.roblocher.com/whitepapers/oletypes.aspx

I recall Allen mentioning mutable value types (!), multiple array and 
date types, and a rising tide of non-compositional types and features.


If we make class-with-private-syntax bespoke and custom, we raise the 
risk of creating some spec-internal new semantics (extending the ES5 
kernel). Besides the loss of ability to mix-and-match functions and 
objects using APIs, as Allen noted, all else equal the odds of loss of 
compositionality go up.


You're right to stress, as Tom and Mark have from the start, that 
private symbols must not pierce membranes (or else a side channel hazard 
exists). That risk exists with bespoke (internal-weakmap-based) 
private-in-class syntax and semantics too. There's no free lunch. Yes, 
weak maps inside the spec avoid this hazard, but they could leak through 
the spec abstraction -- and even if they don't, the lack of 
property-in-object-named-by-private-symbol leaks.


We should stick to the minimize-kernel-semantics plan, and take the 
Scheme Report's intro to heart.


/be


Thanks,

David


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


Re: Security Demands Simplicity (was: Private Slots)

2013-01-20 Thread David Bruant

Le 20/01/2013 21:53, Brendan Eich a écrit :

Allen Wirfs-Brock wrote:
We we were going to talk about adding support for addition semantics 
to  classes we should start at the level of the object model.  Not 
with syntax. ES6 class syntax is good because it is defined in terms 
of the object model and more basic operations that are defined in the 
language.  You don't have to use class syntax to define a class 
equivalent. So, if we are going to introduce private object state the 
first step is to define how it works at the object model level.


Cutting there to dodge the controversy over private-in-class based on 
weak maps, to divide and conquer in the meta-discussion with David.


Here I agree with you, and we have talked in the past of the perils of 
"Scenario Solving" by adding just-so syntax with novel semantics, 
which is not decomposed into orthogonal primitives. You saw that in a 
past life (VB5, cough) and it made messes, even though the intentions 
(serving developer problem-scenarios) were good.
I'm too new to the programming language world, so I don't have this 
context, but I'm curious. Do you have links or further explanations on 
this topic?


Thanks,

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


Re: Security Demands Simplicity (was: Private Slots)

2013-01-20 Thread David Bruant

Le 20/01/2013 23:05, Allen Wirfs-Brock a écrit :

Hopefully.  I think an important characteristic of the current class definition 
syntax is that it conceptually desugars to more primitive features of the 
object model that are exposed to the language.  If you don't like the class 
syntax or want to extend it you can use functional definitional forms or write 
a transpiler that produce identical runtime structures to what is produced by 
class declarations.

If class definitions exploit capabilities that are only available to them, then 
we would loose this characteristic.

True.



On Jan 20, 2013, at 11:12 AM, David Bruant wrote:

"complicated" was an expression. Either proxies don't work with class instances, making 
them vastly pointless or classes need to publicize their private symbols (or maybe expose something 
like "myClass.acceptProxy" which is marginally better), thus ruining their own 
encapsulation.

Actually this whole discussion makes me question the validity of the current 
Proxy design rather than that of private Symbol.  I may be on the road towards 
getting on the NotificationProxy train.
If there is time to make that big of a change, Mark's idea of action 
proxies could be considered too. I've only expressed reluctance on the 
list, because it allows to do weird things when badly used, but for all 
use cases I've had, it would be fine. Tom expressed reluctance regarding 
the cost of action proxies, but I'm not entirely sure it's founded.
Although Notification and action proxies are good to get rid of the 
invariants cost, I'm not entirely sure they can help to reduce the 
complexity when it comes to private symbols.




(...)

This suggests a possible generalized solution to the Proxy/private symbol 
exposure problem:

The [[Get]] and [[Set]]  (and probably some others) internal methods of a proxy never 
call the corresponding trap when the property key is a private Symbol.  Instead, they 
trace the [[Target]] chain of the proxy until a non-proxy object is reached (call this 
the "ultimate target").  It then invokes the ultimate target's [[Gett]]/[[Set]] 
using that same private Symbol key.  The result of that operation is then returned as the 
value of the original [[Get]]/[[Set]].

The "private" state access is applied to the correct object and there is no 
exposure of the private symbol!
It can work for built-in private state (and could work for private class 
syntax too), but not for user-generated or obtained private symbols:
Let's say 2 untrusted parties are in 2 membranes. They share a private 
symbol and each has access to a proxy wrapping a common target. With the 
private symbols semantics you're describing, these 2 untrusted parties 
have an unmediated communication channel.
An unmediated communication channel defeats the purpose of having put 
the 2 untrusted parties in membranes in the first place.
The semantics of user-generated or obtained symbols has to go through 
proxy mediation because of this use case, hence the whitelist and the 
unknownPrivateSymbol trap in the current proxy design.


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


Re: Security Demands Simplicity (was: Private Slots)

2013-01-20 Thread Allen Wirfs-Brock

On Jan 20, 2013, at 4:53 PM, Brendan Eich wrote:

> Allen Wirfs-Brock wrote:
>>> Perhaps you're in favor of that in addition? But if so, how would one proxy 
>>> such that the @@DateValue symbol was the name parameter to get and set 
>>> traps?
>> 
>> I'm not sure if you are getting at something other than what I've described 
>> above.  If a @@DateValue private symbol is actually used as the 
>> implementation of [[DateValue]] then actuality that would happen.
>> 
>> Were you thinking about something different?
> 
> See Brandon's followups. Proxies can tell if an object is fielding direct vs. 
> delegated accesses.


IO'm probably being dense, but I don't seen the issue.  This sounds like 
further support for the idea of direct forwarding of private symbol based 
internal methods to the ultimate target without any observability by the Proxy 
handlers.  

If the concern is abstractions that are directly implemented using Proxy 
(rather than things like membrane wrappers) then the implementation of the 
abstraction knows about this behavior and can structure its target object to 
handle its private Symbol property requests.

Allen
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-20 Thread Allen Wirfs-Brock

On Jan 20, 2013, at 4:46 PM, Brandon Benvie wrote:

>   Err I take it back. They can be implemented in terms of private symbols, 
> but every access has to be guarded with a hasOwn check which would be 
> observable to a Proxy.

Well, proxy observability is the topic of discussion.  they wouldn't be 
observable via the proposal I floated in an earlier message.

Allen




> 
> On Sunday, January 20, 2013, Brandon Benvie wrote:
> On Sunday, January 20, 2013, Allen Wirfs-Brock wrote:
> I'm not sure if you are getting at something other than what I've described 
> above.  If a @@DateValue private symbol is actually used as the 
> implementation of [[DateValue]] then actuality that would happen.
> 
> I explored implementing [[DateValue]], [[NumberValue]], etc. as symbols e.g. 
> @@DateValue, but this causes observably different behavior from what is 
> specified with a.) inheritance, and b.) interaction with proxies. 
> 
> Object.create(new Date).getDate(); // works but is specified to not work
> 
> new Proxy(new Date, {}).getDate(); // works but is specified to not work
> 
> Since Proxy is new in ES6 this of course can still be fixed, but to make the 
> first case work would be a (probably benign) backward incompatible change and 
> isn't going to work cross-engine unless the spec is changed to explicitly 
> allow/require it.

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


Re: Security Demands Simplicity (was: Private Slots)

2013-01-20 Thread Allen Wirfs-Brock

On Jan 20, 2013, at 4:42 PM, Brandon Benvie wrote:

> On Sunday, January 20, 2013, Allen Wirfs-Brock wrote:
> I'm not sure if you are getting at something other than what I've described 
> above.  If a @@DateValue private symbol is actually used as the 
> implementation of [[DateValue]] then actuality that would happen.
> 
> I explored implementing [[DateValue]], [[NumberValue]], etc. as symbols e.g. 
> @@DateValue, but this causes observably different behavior from what is 
> specified with a.) inheritance, and b.) interaction with proxies. 

I spend a lot of time working of Date last week, so you don't have the latests.

In the case of inheritance at least, if it has observably different behavior it 
hasn't been implemented correctly or the spec. is still buggy. 

This is what my working draft currently says:

Unless explicitly stated otherwise, the methods of the Date prototype object 
defined below are not generic and the this value passed to them must be an 
object that has a [[DateValue]] internal data property that has been 
initialized to a time value.

The abstract operation thisTimeValue(value) performs the following steps:

If Type(value) is Object and value has a [[DateValue]] internal data 
property, then
Let n be the Number that is the value of value’s [[NumberData]] 
internal data property.
If n is not undefined, then return n.
Throw a TypeError exception.
In following descriptions of functions that are properties of the Date 
prototype object, the phrase “this Date object” refers to the object that is 
the this value for the invocation of the function. The phrase “this time value” 
within the specification of a method refers to the result returned  by calling 
the abstract operation thisTimeValue with the this value of the method 
invocation passed as the argument. 


> 
> Object.create(new Date).getDate(); // works but is specified to not work

If you are using a private Symbol for [[DateValue]] then the "has a 
[[DateValue]] internal data property" check in the above code needs to do a 
[[HasOwnProperty]] check rather than a [[HasProperty]]

> 
> new Proxy(new Date, {}).getDate(); // works but is specified to not work

Not sure why this works in you implementation.  Can you explain.   

> 
> Since Proxy is new in ES6 this of course can still be fixed, but to make the 
> first case work would be a (probably benign) backward incompatible change and 
> isn't going to work cross-engine unless the spec is changed to explicitly 
> allow/require it.

Right, everything is still in flux which is why it is great that you are trying 
these things. 

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


Re: Security Demands Simplicity (was: Private Slots)

2013-01-20 Thread Brendan Eich

Allen Wirfs-Brock wrote:

Perhaps you're in favor of that in addition? But if so, how would one proxy 
such that the @@DateValue symbol was the name parameter to get and set traps?


I'm not sure if you are getting at something other than what I've described 
above.  If a @@DateValue private symbol is actually used as the implementation 
of [[DateValue]] then actuality that would happen.

Were you thinking about something different?


See Brandon's followups. Proxies can tell if an object is fielding 
direct vs. delegated accesses.


/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-20 Thread Brandon Benvie
  Err I take it back. They can be implemented in terms of private symbols,
but every access has to be guarded with a hasOwn check which would be
observable to a Proxy.

On Sunday, January 20, 2013, Brandon Benvie wrote:

> On Sunday, January 20, 2013, Allen Wirfs-Brock wrote:
>>
>> I'm not sure if you are getting at something other than what I've
>> described above.  If a @@DateValue private symbol is actually used as the
>> implementation of [[DateValue]] then actuality that would happen.
>>
>
> I explored implementing [[DateValue]], [[NumberValue]], etc. as symbols
> e.g. @@DateValue, but this causes observably different behavior from what
> is specified with a.) inheritance, and b.) interaction with proxies.
>
> Object.create(new Date).getDate(); // works but is specified to not
> work
>
> new Proxy(new Date, {}).getDate(); // works but is specified to not
> work
>
> Since Proxy is new in ES6 this of course can still be fixed, but to make
> the first case work would be a (probably benign) backward incompatible
> change and isn't going to work cross-engine unless the spec is changed to
> explicitly allow/require it.
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-20 Thread Brandon Benvie
On Sunday, January 20, 2013, Allen Wirfs-Brock wrote:
>
> I'm not sure if you are getting at something other than what I've
> described above.  If a @@DateValue private symbol is actually used as the
> implementation of [[DateValue]] then actuality that would happen.
>

I explored implementing [[DateValue]], [[NumberValue]], etc. as symbols
e.g. @@DateValue, but this causes observably different behavior from what
is specified with a.) inheritance, and b.) interaction with proxies.

Object.create(new Date).getDate(); // works but is specified to not work

new Proxy(new Date, {}).getDate(); // works but is specified to not work

Since Proxy is new in ES6 this of course can still be fixed, but to make
the first case work would be a (probably benign) backward incompatible
change and isn't going to work cross-engine unless the spec is changed to
explicitly allow/require it.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-20 Thread Allen Wirfs-Brock

On Jan 20, 2013, at 2:27 PM, Brendan Eich wrote:

> Skipping contentious stuff (some of which, e.g. "classes as sugar", I agree 
> with -- and so does TC39) to get to this paragraph:
> 
> Allen Wirfs-Brock wrote:
>> The [[Get]] and [[Set]]  (and probably some others) internal methods of a 
>> proxy never call the corresponding trap when the property key is a private 
>> Symbol.  Instead, they trace the [[Target]] chain of the proxy until a 
>> non-proxy object is reached (call this the "ultimate target").  It then 
>> invokes the ultimate target's [[Gett]]/[[Set]] using that same private 
>> Symbol key.  The result of that operation is then returned as the value of 
>> the original [[Get]]/[[Set]].
>> 
>> The "private" state access is applied to the correct object and there is no 
>> exposure of the private symbol!
> 
> If I want to proxy for a date instance I might rather have @@DateValue 
> available and passed as a name to get and set traps, so I can keep my own 
> time number, and not have to delegate to a Date prototype that has the right 
> milliseconds since the Epoch.

For the above I'm thinking of situations where an external party (a membrane?) 
is wrapping an object that wasn't specifically designed to be proxied.  That 
presumably is the use case that people are primarily concerned about in the 
recent discussions.   As far as I can tell, without special accommodations for 
all the built-ins' internal state they just don't work if proxied  in that 
manner because the "wrong" this value is passed to all of the methods. Same as 
for previous proposal for censoring private symbols. 

I actually don't see why you would ever need to use a Proxy to implement a ES 
compatible data abstraction.  There is nothing about that abstractions (unlike 
Array, for example) that requires changing the MOP level behavior manifested by 
its instances.

Mostly what we are dealing with, WRT Date, is balancing legacy compatibility 
issues with subclassability issues.  The legacy spec for all the Date prototype 
methods says they throw if they are applied to a this value that does not have 
the internal state of a Date instance.  Among other things, this allows 
implementations to use custom c structs for Date instances and implement access 
to the timeValue as a impl level brand check followed by a direct slot access.  
The ES6 specification of these methods is intentionally vague (the timeValue is 
in the [[DaveValue]] "internal data property" (which could be implemented using 
a private Symbol keyed property) rather than explicitly specified as a private 
Symbol keyed property.  This (along with the @@create method) allows subclass 
to have the same private state layout as the superclass and allows it to be 
recognized by the methods.

Because of this design, the Date prototype methods are only usable on objects 
that are allocated using Date.@@create (subclasses achieve this via class-side 
inheritance).  It would arguably be a better OO design to have all those 
methods access the timeValue via a specified @@DateValue method call.  Then 
they could be install on any object that supplies (possibly via inheritance) 
such a method.  But that design seems to make it harder to use an optimization 
object struct and possibly to perfectly duplicate the legacy failure behavior.

> 
> Perhaps you're in favor of that in addition? But if so, how would one proxy 
> such that the @@DateValue symbol was the name parameter to get and set traps?

I'm not sure if you are getting at something other than what I've described 
above.  If a @@DateValue private symbol is actually used as the implementation 
of [[DateValue]] then actuality that would happen. 

Were you thinking about something different?

Allen



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


Re: Security Demands Simplicity (was: Private Slots)

2013-01-20 Thread Brendan Eich
Skipping contentious stuff (some of which, e.g. "classes as sugar", I 
agree with -- and so does TC39) to get to this paragraph:


Allen Wirfs-Brock wrote:

The [[Get]] and [[Set]]  (and probably some others) internal methods of a proxy never 
call the corresponding trap when the property key is a private Symbol.  Instead, they 
trace the [[Target]] chain of the proxy until a non-proxy object is reached (call this 
the "ultimate target").  It then invokes the ultimate target's [[Gett]]/[[Set]] 
using that same private Symbol key.  The result of that operation is then returned as the 
value of the original [[Get]]/[[Set]].

The "private" state access is applied to the correct object and there is no 
exposure of the private symbol!


If I want to proxy for a date instance I might rather have @@DateValue 
available and passed as a name to get and set traps, so I can keep my 
own time number, and not have to delegate to a Date prototype that has 
the right milliseconds since the Epoch.


Perhaps you're in favor of that in addition? But if so, how would one 
proxy such that the @@DateValue symbol was the name parameter to get and 
set traps?


/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-20 Thread Allen Wirfs-Brock

On Jan 20, 2013, at 11:12 AM, David Bruant wrote:

> Le 20/01/2013 18:54, Allen Wirfs-Brock a écrit :
>> On Jan 20, 2013, at 3:04 AM, David Bruant wrote:
>> 
>>> Le 20/01/2013 05:27, Allen Wirfs-Brock a écrit :
 Weakmaps and symbol keyed properties (private or not) are very different 
 mechanism.  They each have a variety of uses and differing implementation 
 and performance characteristics.  It really is a distraction to focus 
 exclusively on a single use case that might be supported by two different 
 mechanism and use it to argue that only one of the mechanism is needed.
>>> What are the different uses of private symbols?
>> Branding is the important one.
>> 
>> Secure private communications between "friend" objects is another possible 
>> one.
> Secure private communication between friend objects can be achieved simply 
> and efficiently with functions or weakmaps already. Why is there a need for 
> an additional construct for that use case?

You didn't address branding.

Also, here is another use case.  Self hosting the ES built-in library, which 
makes extensive use of private internal state.

I don't think you can make valid statements about simplicity and efficiencies 
without working through more specific use cases.  I have a fundamental 
disagreement with arguments that start with the premise that WeakMaps and 
private Symbol keyed properties have comparable performance profiles.  

> 
>>> More specifically: what are the remaining explicit uses of private symbols 
>>> in a language with private syntax in classes?
>> But we don't have such a language.  There are no harmonious proposals for 
>> such a syntax.  Getting classes into ES6 via the max-min class proposal was 
>> possible because we agreed not to debate that issue.
> Will we ever? If the answer is yes, my point stands. TypeScript has private 
> syntax in class. People want it. The ES6 cut-off was too short for TC39 to 
> settle on private in class, but the pressure is here so it's going to happen 
> sooner or later (Mark was saying ES7).

The problem wasn't that the ES6 cut-off was too short to get private into 
class.  The problem was that we couldn't agree upon a meaning (or syntax) for 
private in classes and it was preventing the inclusion of any class syntax.  I 
don't know how long it will take to resolve this.  Never is always a 
possibility.

TypeScript private is not what you want.  The are a purely compile-time 
construct and don't provide any strong runtime encapsulation.

> 
>> We we were going to talk about adding support for addition semantics to  
>> classes we should start at the level of the object model.  Not with syntax. 
>> ES6 class syntax is good because it is defined in terms of the object model 
>> and more basic operations that are defined in the language.  You don't have 
>> to use class syntax to define a class equivalent. So, if we are going to 
>> introduce private object state the first step is to define how it works at 
>> the object model level.
> Does defining how it works at the object model level commits the language to 
> expose a runtime construct allowing to use the lowest-level feature directly?

Hopefully.  I think an important characteristic of the current class definition 
syntax is that it conceptually desugars to more primitive features of the 
object model that are exposed to the language.  If you don't like the class 
syntax or want to extend it you can use functional definitional forms or write 
a transpiler that produce identical runtime structures to what is produced by 
class declarations.

If class definitions exploit capabilities that are only available to them, then 
we would loose this characteristic.

> I think it does not. You think it does, hence private symbols:
> * For which benefits?
> * One downside is that it brings along more complexity to the language... 
> well... to proxies at least. I understand and somewhat agree with your 
> argument that complexifying proxies isn't a problem, but at least, there 
> should be a benefit.
> Also, given that private-in-classes aren't in ES6, why would it be necessary 
> to add private symbols in ES6? Until there is a feature that demands to be 
> desugared as private symbols (I don't think there is, but you probably know 
> better, so tell me if so), it might be wise to put them on hold.

Branding of a large population of highly volatile object instances.  The need 
to do this is completely orthogonal with classes. Arguably private symbols adds 
no complexity to the actual syntactic ES language, but only to the standard 
library (including the Proxy handler API).

> 
>> IMO and for reasons I've already presented, saying that private state is 
>> just relationships defined via WeakMaps is a non-starter.
> I disagree with your arguments on WeakMaps, because choosing to desugar the 
> syntax to WeakMaps doesn't commit neither the implementation nor the spec to 
> actually use weakmaps to spec or to implement the feature.

Re: Security Demands Simplicity (was: Private Slots)

2013-01-20 Thread Brendan Eich

Allen Wirfs-Brock wrote:

We we were going to talk about adding support for addition semantics to  
classes we should start at the level of the object model.  Not with syntax. ES6 
class syntax is good because it is defined in terms of the object model and 
more basic operations that are defined in the language.  You don't have to use 
class syntax to define a class equivalent. So, if we are going to introduce 
private object state the first step is to define how it works at the object 
model level.


Cutting there to dodge the controversy over private-in-class based on 
weak maps, to divide and conquer in the meta-discussion with David.


Here I agree with you, and we have talked in the past of the perils of 
"Scenario Solving" by adding just-so syntax with novel semantics, which 
is not decomposed into orthogonal primitives. You saw that in a past 
life (VB5, cough) and it made messes, even though the intentions 
(serving developer problem-scenarios) were good.


I think TC39 as a whole agrees.

But this doesn't settle the private-in-class-on-weak-map hash, IMHO.

/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-20 Thread Brendan Eich

David Bruant wrote:

Le 20/01/2013 19:01, Brendan Eich a écrit :

David Bruant wrote:
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. 


See http://wiki.ecmascript.org/doku.php?id=harmony:harmony, in 
particular



   Means

1.
   Minimize the additional semantic state needed beyond ES5.
2.
   Provide syntactic conveniences for:
1.
   good abstraction patterns;
2.
   high integrity patterns;
3.
   defined by desugaring into kernel semantics.


We aim to unify the "spec problem" and the "transpiler problem" where 
possible.
I think the goal of providing syntactic conveniences defined by 
desugaring into kernel semantics is a valuable goal. It's good to 
reason about this semantics and it's good for transpilers.
I however disagree that it should be taken to the letter as Allen 
seems to take it. Specifically, I disagree with the idea that all 
kernal semantics should be exposed as runtime constructs. They should 
only if they prove to be useful for some other purpose.


Hence my "where possible".

Note the Reference internal type among others.

Please do try to avoid casting positions as absolute when they 
explicitly are not.



Not always, not necessarily by spec-by-desugaring.
But we don't want magic in the spec that leaves transpilers falling 
into the tarpit, if we can avoid it.
Semantics of private-class syntax hasn't been agreed on, so it's hard 
to say if transpilers would have a hard time with the 
eventually-agreed semantics, but Mark's desugaring with WeakMaps could 
work, couldn't it?


Do we want protected? Do we have an issue (Kevin is getting at this) 
with proxies observing that private-in-class is based on something other 
than properties named by private symbols?


If proxies can observe that, yes, you are right: we may still use 
internal spec types to specify private-in-class. But we should also 
consider using weak maps and supporting transpilers, and committing to 
any observables.


Doing so closes the door to private symbols in the future, in my view.

/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-20 Thread Brendan Eich

David Bruant wrote:

Le 20/01/2013 18:59, Brendan Eich a écrit :

David Bruant wrote:
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). 


I don't think we disagree.

If there were no observable differences at all between weak maps and 
private symbols, we would have only one. Since there are, and since 
you propose to map private-in-class syntax onto weak maps in part on 
account of these differences (viz, proxying and whitelist population 
without privacy-leaks), here we are.

I don't understand, this paragraph went too quickly.
I understand that you're saying that the proposal I defend (which 
includes getting rid of private symbols) relies on the differences 
between private symbols and weakmaps and hence both are necessary?

Am I fully misunderstanding?


I think you are misreading, and we're going off track. You did not agree 
with my use of "use". I'm not sure why, but my second reply about 
wanting to minimize kernel semantics in the spec, and thereby support 
desugaring/trans-compilation, may shed light on the deeper issue (if 
there is one).


In none of this did I try to make a case for private symbols and weak 
maps. That case has been made but I'm not going to rehash it, and your 
argument predicated on private-in-class for weak maps is a fine argument 
to make (assuming the predicate condition, which is not true for ES6 -- 
no private syntax in class syntax yet!).


/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-20 Thread David Bruant

Le 20/01/2013 19:01, Brendan Eich a écrit :

David Bruant wrote:
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. 


See http://wiki.ecmascript.org/doku.php?id=harmony:harmony, in particular


   Means

1.
   Minimize the additional semantic state needed beyond ES5.
2.
   Provide syntactic conveniences for:
1.
   good abstraction patterns;
2.
   high integrity patterns;
3.
   defined by desugaring into kernel semantics.


We aim to unify the "spec problem" and the "transpiler problem" where 
possible.
I think the goal of providing syntactic conveniences defined by 
desugaring into kernel semantics is a valuable goal. It's good to reason 
about this semantics and it's good for transpilers.
I however disagree that it should be taken to the letter as Allen seems 
to take it. Specifically, I disagree with the idea that all kernal 
semantics should be exposed as runtime constructs. They should only if 
they prove to be useful for some other purpose.



Not always, not necessarily by spec-by-desugaring.
But we don't want magic in the spec that leaves transpilers falling 
into the tarpit, if we can avoid it.
Semantics of private-class syntax hasn't been agreed on, so it's hard to 
say if transpilers would have a hard time with the eventually-agreed 
semantics, but Mark's desugaring with WeakMaps could work, couldn't it?


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


Re: Security Demands Simplicity (was: Private Slots)

2013-01-20 Thread David Bruant

Le 20/01/2013 18:54, Allen Wirfs-Brock a écrit :

On Jan 20, 2013, at 3:04 AM, David Bruant wrote:


Le 20/01/2013 05:27, Allen Wirfs-Brock a écrit :

Weakmaps and symbol keyed properties (private or not) are very different 
mechanism.  They each have a variety of uses and differing implementation and 
performance characteristics.  It really is a distraction to focus exclusively 
on a single use case that might be supported by two different mechanism and use 
it to argue that only one of the mechanism is needed.

What are the different uses of private symbols?

Branding is the important one.

Secure private communications between "friend" objects is another possible one.
Secure private communication between friend objects can be achieved 
simply and efficiently with functions or weakmaps already. Why is there 
a need for an additional construct for that use case?



More specifically: what are the remaining explicit uses of private symbols in a 
language with private syntax in classes?

But we don't have such a language.  There are no harmonious proposals for such 
a syntax.  Getting classes into ES6 via the max-min class proposal was possible 
because we agreed not to debate that issue.
Will we ever? If the answer is yes, my point stands. TypeScript has 
private syntax in class. People want it. The ES6 cut-off was too short 
for TC39 to settle on private in class, but the pressure is here so it's 
going to happen sooner or later (Mark was saying ES7).



We we were going to talk about adding support for addition semantics to  
classes we should start at the level of the object model.  Not with syntax. ES6 
class syntax is good because it is defined in terms of the object model and 
more basic operations that are defined in the language.  You don't have to use 
class syntax to define a class equivalent. So, if we are going to introduce 
private object state the first step is to define how it works at the object 
model level.
Does defining how it works at the object model level commits the 
language to expose a runtime construct allowing to use the lowest-level 
feature directly?

I think it does not. You think it does, hence private symbols:
* For which benefits?
* One downside is that it brings along more complexity to the 
language... well... to proxies at least. I understand and somewhat agree 
with your argument that complexifying proxies isn't a problem, but at 
least, there should be a benefit.
Also, given that private-in-classes aren't in ES6, why would it be 
necessary to add private symbols in ES6? Until there is a feature that 
demands to be desugared as private symbols (I don't think there is, but 
you probably know better, so tell me if so), it might be wise to put 
them on hold.



IMO and for reasons I've already presented, saying that private state is just 
relationships defined via WeakMaps is a non-starter.
I disagree with your arguments on WeakMaps, because choosing to desugar 
the syntax to WeakMaps doesn't commit neither the implementation nor the 
spec to actually use weakmaps to spec or to implement the feature.




I think symbols were introduced given experience in ES5 and assuming being an 
improvement on top of ES5 as we know it. On top of pure ES5, private symbols 
make a lot of sense. In ES5+class-with-private-syntax, I'm much more skeptical.

Actually experience with a number of languages.  But like I said, there is no 
ES5+class-with-private-syntax so I don't see how that is a useful argument.

There will be.


Also, private syntax as private symbol makes the proxy story complicated [1], 
because the class or its instances need to publicize private symbols so that 
proxies can add them to their whitelist when wrapping class instances. I don't 
think leaking abstraction is a valid option, so it means that only 2 out of the 
3 following can be kept in the language:

I don't have a problem at all with making the proxy story more complicated.
"complicated" was an expression. Either proxies don't work with class 
instances, making them vastly pointless or classes need to publicize 
their private symbols (or maybe expose something like 
"myClass.acceptProxy" which is marginally better), thus ruining their 
own encapsulation.



Proxys are an expert feature designed for some specific use cases.  they are 
probably an attractive nuisance.  I would advise most JS programmer that if 
they are going down the road of using a Proxy, they are probably making a 
mistake.  In that light,  placing the extra complexity within the Proxy story 
seems just fine.
To the point of making proxies useless when interacting with class 
instances or ruining class encapsulation?



1) proxy-wrapping class instances (without leaking abstractions)
2) private syntax in class
3) private symbols
We can probably predict in advance that JavaScript authors will largely not 
want to give up on 2) (even if it comes only in ES7). Should 1) or 3) be given 
up? Unless relevant use cases different than class-like usage

Re: Security Demands Simplicity (was: Private Slots)

2013-01-20 Thread David Bruant

Le 20/01/2013 18:59, Brendan Eich a écrit :

David Bruant wrote:
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). 


I don't think we disagree.

If there were no observable differences at all between weak maps and 
private symbols, we would have only one. Since there are, and since 
you propose to map private-in-class syntax onto weak maps in part on 
account of these differences (viz, proxying and whitelist population 
without privacy-leaks), here we are.

I don't understand, this paragraph went too quickly.
I understand that you're saying that the proposal I defend (which 
includes getting rid of private symbols) relies on the differences 
between private symbols and weakmaps and hence both are necessary?

Am I fully misunderstanding?

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


Re: Security Demands Simplicity (was: Private Slots)

2013-01-20 Thread Brendan Eich

David Bruant wrote:
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. 


See http://wiki.ecmascript.org/doku.php?id=harmony:harmony, in particular


   Means

1.
   Minimize the additional semantic state needed beyond ES5.
2.
   Provide syntactic conveniences for:
1.
   good abstraction patterns;
2.
   high integrity patterns;
3.
   defined by desugaring into kernel semantics.


We aim to unify the "spec problem" and the "transpiler problem" where 
possible. Not always, not necessarily by spec-by-desugaring. But we 
don't want magic in the spec that leaves transpilers falling into the 
tarpit, if we can avoid it.


/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-20 Thread Brendan Eich

David Bruant wrote:
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). 


I don't think we disagree.

If there were no observable differences at all between weak maps and 
private symbols, we would have only one. Since there are, and since you 
propose to map private-in-class syntax onto weak maps in part on account 
of these differences (viz, proxying and whitelist population without 
privacy-leaks), here we are.


Perhaps I should have written "utilize"? Bleah.

/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-20 Thread Allen Wirfs-Brock

On Jan 20, 2013, at 3:04 AM, David Bruant wrote:

> Le 20/01/2013 05:27, Allen Wirfs-Brock a écrit :
>> Weakmaps and symbol keyed properties (private or not) are very different 
>> mechanism.  They each have a variety of uses and differing implementation 
>> and performance characteristics.  It really is a distraction to focus 
>> exclusively on a single use case that might be supported by two different 
>> mechanism and use it to argue that only one of the mechanism is needed.
> What are the different uses of private symbols?

Branding is the important one.

Secure private communications between "friend" objects is another possible one. 

> More specifically: what are the remaining explicit uses of private symbols in 
> a language with private syntax in classes?

But we don't have such a language.  There are no harmonious proposals for such 
a syntax.  Getting classes into ES6 via the max-min class proposal was possible 
because we agreed not to debate that issue.

We we were going to talk about adding support for addition semantics to  
classes we should start at the level of the object model.  Not with syntax. ES6 
class syntax is good because it is defined in terms of the object model and 
more basic operations that are defined in the language.  You don't have to use 
class syntax to define a class equivalent. So, if we are going to introduce 
private object state the first step is to define how it works at the object 
model level.   IMO and for reasons I've already presented, saying that private 
state is just relationships defined via WeakMaps is a non-starter.

> 
> I think symbols were introduced given experience in ES5 and assuming being an 
> improvement on top of ES5 as we know it. On top of pure ES5, private symbols 
> make a lot of sense. In ES5+class-with-private-syntax, I'm much more 
> skeptical.

Actually experience with a number of languages.  But like I said, there is no 
ES5+class-with-private-syntax so I don't see how that is a useful argument.
> 
> Also, private syntax as private symbol makes the proxy story complicated [1], 
> because the class or its instances need to publicize private symbols so that 
> proxies can add them to their whitelist when wrapping class instances. I 
> don't think leaking abstraction is a valid option, so it means that only 2 
> out of the 3 following can be kept in the language:

I don't have a problem at all with making the proxy story more complicated.  
Proxys are an expert feature designed for some specific use cases.  they are 
probably an attractive nuisance.  I would advise most JS programmer that if 
they are going down the road of using a Proxy, they are probably making a 
mistake.  In that light,  placing the extra complexity within the Proxy story 
seems just fine.  

> 1) proxy-wrapping class instances (without leaking abstractions)
> 2) private syntax in class
> 3) private symbols
> We can probably predict in advance that JavaScript authors will largely not 
> want to give up on 2) (even if it comes only in ES7). Should 1) or 3) be 
> given up? Unless relevant use cases different than class-like usages are 
> provided, 3) can disappear in my opinion.

If the above was the only choice (and I don't think it is) I would probably 
pick #1 to eliminate.

Allen

> 
> David
> 
> [1] https://mail.mozilla.org/pipermail/es-discuss/2013-January/028285.html
> 

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


Re: Security Demands Simplicity (was: Private Slots)

2013-01-20 Thread Juan Ignacio Dopazo
2013/1/17 Mark S. Miller 

> By the time ES7 rolls out, there will be a lot of that code.
>

I very much agree and I think we may see that sooner. I wrote a gist (
https://gist.github.com/2901426) using WeakMaps for privates about 7 months
ago, before this discussion. I expect to see code like that in the wild
once WeakMaps get to Node without a flag.

I think the nicest thing about specifying privates with WeakMaps is that
using it in a transpiler would be seamless. There wouldn't be any
functionality lost. And that would be specially good since browsers are
implementing new APIs before new syntax. That means we could get privates
sooner!

Juan
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-20 Thread Kevin Smith
Got it.  And one more (thanks for bearing with me):  what affect does
throwing an error have within a trap?

var target = {
  foo: function() { this.bar; console.log("after bar"); },
  bar: 0
};

var proxy = new Proxy(target, {
  get: function(obj, name) {
if (name === "bar") throw new Error("boom");
return obj[name];
  }
});

proxy.foo();

Does the stack unwind as with normal error handling?  Does "after bar" get
logged?  (FF18 answers yes to the first and no to the second question.)

{ Kevin }
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-20 Thread David Bruant

Le 20/01/2013 06:36, Kevin Smith a écrit :


It is not. At the exit of the get trap, the JS engine checks
whether invariants should be enforced for the given property on
the target. In your case, the runtime sees that the target has a
non-configurable non-writable property called 'foo' with 1 as
value. When you try to return 0, it will throw a TypeError because
of invariant violation. You can read about invariants at

http://wiki.ecmascript.org/doku.php?id=harmony:direct_proxies#invariant_enforcement


Excellent - thanks for the link!  One more:  What is the reason for 
not providing an API for unwrapping a proxy (e.g. your 
proxyToFinalTarget)?
If anyone can unwrap proxies, then the security benefits they provide 
are virtually non-existent akin to the Reflect API in Java.
It's possible to implement such a function yourself and expose it for 
some of your proxies, but it should be an opt-in, not something 
available by default to everyone in the language.


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


Re: Security Demands Simplicity (was: Private Slots)

2013-01-20 Thread David Bruant

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 sep

Re: Security Demands Simplicity (was: Private Slots)

2013-01-20 Thread David Bruant

Le 20/01/2013 05:27, Allen Wirfs-Brock a écrit :

Weakmaps and symbol keyed properties (private or not) are very different 
mechanism.  They each have a variety of uses and differing implementation and 
performance characteristics.  It really is a distraction to focus exclusively 
on a single use case that might be supported by two different mechanism and use 
it to argue that only one of the mechanism is needed.

What are the different uses of private symbols?
More specifically: what are the remaining explicit uses of private 
symbols in a language with private syntax in classes?


I think symbols were introduced given experience in ES5 and assuming 
being an improvement on top of ES5 as we know it. On top of pure ES5, 
private symbols make a lot of sense. In ES5+class-with-private-syntax, 
I'm much more skeptical.


Also, private syntax as private symbol makes the proxy story complicated 
[1], because the class or its instances need to publicize private 
symbols so that proxies can add them to their whitelist when wrapping 
class instances. I don't think leaking abstraction is a valid option, so 
it means that only 2 out of the 3 following can be kept in the language:

1) proxy-wrapping class instances (without leaking abstractions)
2) private syntax in class
3) private symbols
We can probably predict in advance that JavaScript authors will largely 
not want to give up on 2) (even if it comes only in ES7). Should 1) or 
3) be given up? Unless relevant use cases different than class-like 
usages are provided, 3) can disappear in my opinion.


David

[1] https://mail.mozilla.org/pipermail/es-discuss/2013-January/028285.html
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-19 Thread Allen Wirfs-Brock

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.

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

Private Symbols and Weakmaps are both useful mechanism that are naturally 
optimized for different use cases.  We wouldn't be making the world simpler by 
requiring that Weakmaps be used for all those use cases.

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.

Allen

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


Re: Security Demands Simplicity (was: Private Slots)

2013-01-19 Thread Kevin Smith
> It is not. At the exit of the get trap, the JS engine checks whether
> invariants should be enforced for the given property on the target. In your
> case, the runtime sees that the target has a non-configurable non-writable
> property called 'foo' with 1 as value. When you try to return 0, it will
> throw a TypeError because of invariant violation. You can read about
> invariants at
> http://wiki.ecmascript.org/doku.php?id=harmony:direct_proxies#invariant_enforcement
>
>
Excellent - thanks for the link!  One more:  What is the reason for not
providing an API for unwrapping a proxy (e.g. your proxyToFinalTarget)?

{ Kevin }
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-19 Thread Brendan Eich

Allen Wirfs-Brock wrote:

On Jan 19, 2013, at 6:02 PM, Brendan Eich wrote:

Frozen objects could even be promoted by a copying GC into read-only memory, 
with the OS virtualized hardware MMU providing greater integrity.


But here you are talking about some broader from of immutability that presumably includes 
non-property per instance state (eg, "internal data properties") and any sort of 
"private" per instance state that the language provides.  Either of those go beyond what 
ES5 Object.preventExtensions or even Object.freeze  provides.


No, I'm talking about plain old Object instances that are frozen and 
live long enough.



More to the point, programmers may wish a frozen object o having properties p 
and q, and null or frozen prototype chain of known properties, never to grow 
property r. Whereas using weakmaps explicitly, of course one can call r.set(o, 
v) to set r's value to v.


Right, they may. My point we is that we have to decide on all the characteristics of a 
"frozen" object before we can answer all of these questions.

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.


   Such a relationship is an independent entity that exists separately from o 
and can be defined independently of o.

If we are talking about private syntax only in classes, this may not matter. 
Either private symbols or weak maps suffice.


I think a very important characteristic of classes is that they really are just 
sugar and don't have any special magic. We should try to maintain that 
characteristic.


That seems to be agreed upon by everyone (anyone dissent?).


But proxies can tell, and prototype-based inheritance works for private symbols 
but not weak maps.

So even if we allow a frozen object to grow new private-symbol-keyed properties 
not in that object at the time it was frozen (or let's say the time 
Object.preventExtensions or its internal form was invoked), private symbols and 
weak maps are distinguishable. If they weren't, we surely would have no need 
for one or the other.


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.



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


/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-19 Thread Allen Wirfs-Brock

On Jan 19, 2013, at 6:36 PM, Mark S. Miller wrote:

> On Sat, Jan 19, 2013 at 5:15 PM, Allen Wirfs-Brock
>  wrote:
>> 
>> On Jan 19, 2013, at 11:39 AM, Brendan Eich wrote:
>> 
>>> Something was nagging me from the 2011-era debate over private symbols vs. 
>>> weak maps, and that's the ability of a weak map to implement soft fields on 
>>> frozen objects. Symbols (private or not) can't do that.
>>> 
>>> Not sure this matters in the current proxy-focused thread, but I thought I 
>>> would point it out explicitly.
>> 
>> It seems like at the root of this question revolves around what you mean by 
>> a "frozen object".
>> 
>> In ES5 there is no such concept.  There really is only the 
>> Object.freeze/Object.isFrozen functions.  These are defined operationally in 
>> terms of specific constructs that exist in ES5.  There really is no guidance 
>> in those definitions as to how they should be extended when when new 
>> constructs are added to the language.
>> 
>> Also, the effect obtained by applying Object.freeze to an object isn't a 
>> fundamental characteristic of an object.  The exact same effect can be 
>> achieve by a combination of other calls and Object.isFreeze will still 
>> report true.
>> 
>> Who's to say that a symbol keyed object can't be added to an object after 
>> Object.freeze has been applied to it.
> 
> Me. We've been over this. With the semantics you suggest, sharing an
> immutable object and an immutable Symbol opens a communications
> channel. That is why the private symbol freeze exemption exempted
> private-symbol-named properties from the non-writability and
> non-configurability of freeze, but only for properties that were
> already there. Private symbols must not be exempt from
> non-extensibility, or you get an unpluggable channel.

Just to be clear, I'm not arguing for any specific semantics.  I'm just saying 
we can't compare alternative solutions to a problem until we have defined all 
the requirements.  Brendan, in his initial reply to my comment, suggested some 
possible requirements that ES5 Object.freeze or Object.preventExtensions 
probably don't meet even if we ignore the existence of symbols.

> 
> WeakMaps don't have this problem because you can only add a key to a
> mutable weakmap. We can account for the mutablity in terms of
> explicitly mutable state. An immutable weakmap, easily achieved by a
> trivial wrapping of a weakmap, allows lookup but no further additions,
> thereby not opening up a communications channel. And weakmaps don't
> need magic exemptions, partial or otherwise.

There is no "magic" involved with private symbols, it is just a small matter of 
specifying how they interact with existing reflection operations. In contrast,  
if you want relationships formed using Weakmap to appear as if they were object 
properties then you are asking for an illusion that takes real magic.

I'll partially repeat myself from my reply to Brendan.  Just because you have 
two mechanisms that can solve the same program doesn't mean that they are 
equivalent or that one the mechanism is necessarily redundant.  Weakmaps and 
symbol keyed properties (private or not) are very different mechanism.  They 
each have a variety of uses and differing implementation and performance 
characteristics.  It really is a distraction to focus exclusively on a single 
use case that might be supported by two different mechanism and use it to argue 
that only one of the mechanism is needed.

> 
>> Before we can say that we have to define the semantics of symbol keyed 
>> objects and possibly extend Object.freeze/isFrozen to accommodate those new 
>> semantics. What's the guidance for doing so?  What abstract concept of 
>> "frozen" do we to apply to the semantics of new language features?
> 
> Let's start with support for ocap reasoning. Or even info flow
> reasoning for that matter, which is sufficient for the above issues.

OK, those requires are?


Allen
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-19 Thread Allen Wirfs-Brock

On Jan 19, 2013, at 6:02 PM, Brendan Eich wrote:

> Allen Wirfs-Brock wrote:
>> Who's to say that a symbol keyed object
> 
> You must mean "property" not "object".

of couse
> 
>>  can't be added to an object after Object.freeze has been applied to it.  
>> Before we can say that we have to define the semantics of symbol keyed 
>> objects and possibly extend Object.freeze/isFrozen to accommodate those new 
>> semantics. What's the guidance for doing so?  What abstract concept of 
>> "frozen" do we to apply to the semantics of new language features?
> 
> This is not an abstract question. Implementors may want 
> Object.preventExtensions to put an object in a state such that optimizations 
> can rely on it never growing new properties.

Then are we talking about what I would probably call non-extensible objects.  
You are saying you want the "shape" of the object to be fixed. 

> Frozen objects could even be promoted by a copying GC into read-only memory, 
> with the OS virtualized hardware MMU providing greater integrity.

But here you are talking about some broader from of immutability that 
presumably includes non-property per instance state (eg, "internal data 
properties") and any sort of "private" per instance state that the language 
provides.  Either of those go beyond what ES5 Object.preventExtensions or even 
Object.freeze  provides.

> 
> More to the point, programmers may wish a frozen object o having properties p 
> and q, and null or frozen prototype chain of known properties, never to grow 
> property r. Whereas using weakmaps explicitly, of course one can call 
> r.set(o, v) to set r's value to v.

Right, they may. My point we is that we have to decide on all the 
characteristics of a "frozen" object before we can answer all of these 
questions.

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.  Such a relationship is an 
independent entity that exists separately from o and can be defined 
independently of o. 
> 
> If we are talking about private syntax only in classes, this may not matter. 
> Either private symbols or weak maps suffice.

I think a very important characteristic of classes is that they really are just 
sugar and don't have any special magic. We should try to maintain that 
characteristic. 


> But proxies can tell, and prototype-based inheritance works for private 
> symbols but not weak maps.
> 
> So even if we allow a frozen object to grow new private-symbol-keyed 
> properties not in that object at the time it was frozen (or let's say the 
> time Object.preventExtensions or its internal form was invoked), private 
> symbols and weak maps are distinguishable. If they weren't, we surely would 
> have no need for one or the other.

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. 

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);
   }
}


Allen


> 
> /be
> 

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


Re: Security Demands Simplicity (was: Private Slots)

2013-01-19 Thread Mark S. Miller
On Sat, Jan 19, 2013 at 5:15 PM, Allen Wirfs-Brock
 wrote:
>
> On Jan 19, 2013, at 11:39 AM, Brendan Eich wrote:
>
>> Something was nagging me from the 2011-era debate over private symbols vs. 
>> weak maps, and that's the ability of a weak map to implement soft fields on 
>> frozen objects. Symbols (private or not) can't do that.
>>
>> Not sure this matters in the current proxy-focused thread, but I thought I 
>> would point it out explicitly.
>
> It seems like at the root of this question revolves around what you mean by a 
> "frozen object".
>
> In ES5 there is no such concept.  There really is only the 
> Object.freeze/Object.isFrozen functions.  These are defined operationally in 
> terms of specific constructs that exist in ES5.  There really is no guidance 
> in those definitions as to how they should be extended when when new 
> constructs are added to the language.
>
> Also, the effect obtained by applying Object.freeze to an object isn't a 
> fundamental characteristic of an object.  The exact same effect can be 
> achieve by a combination of other calls and Object.isFreeze will still report 
> true.
>
> Who's to say that a symbol keyed object can't be added to an object after 
> Object.freeze has been applied to it.

Me. We've been over this. With the semantics you suggest, sharing an
immutable object and an immutable Symbol opens a communications
channel. That is why the private symbol freeze exemption exempted
private-symbol-named properties from the non-writability and
non-configurability of freeze, but only for properties that were
already there. Private symbols must not be exempt from
non-extensibility, or you get an unpluggable channel.

WeakMaps don't have this problem because you can only add a key to a
mutable weakmap. We can account for the mutablity in terms of
explicitly mutable state. An immutable weakmap, easily achieved by a
trivial wrapping of a weakmap, allows lookup but no further additions,
thereby not opening up a communications channel. And weakmaps don't
need magic exemptions, partial or otherwise.

>  Before we can say that we have to define the semantics of symbol keyed 
> objects and possibly extend Object.freeze/isFrozen to accommodate those new 
> semantics. What's the guidance for doing so?  What abstract concept of 
> "frozen" do we to apply to the semantics of new language features?

Let's start with support for ocap reasoning. Or even info flow
reasoning for that matter, which is sufficient for the above issues.

>
> Allen
>
>



--
Cheers,
--MarkM
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-19 Thread Brendan Eich

Allen Wirfs-Brock wrote:

Who's to say that a symbol keyed object


You must mean "property" not "object".


  can't be added to an object after Object.freeze has been applied to it.  Before we can 
say that we have to define the semantics of symbol keyed objects and possibly extend 
Object.freeze/isFrozen to accommodate those new semantics. What's the guidance for doing 
so?  What abstract concept of "frozen" do we to apply to the semantics of new 
language features?


This is not an abstract question. Implementors may want 
Object.preventExtensions to put an object in a state such that 
optimizations can rely on it never growing new properties. Frozen 
objects could even be promoted by a copying GC into read-only memory, 
with the OS virtualized hardware MMU providing greater integrity.


More to the point, programmers may wish a frozen object o having 
properties p and q, and null or frozen prototype chain of known 
properties, never to grow property r. Whereas using weakmaps explicitly, 
of course one can call r.set(o, v) to set r's value to v.


If we are talking about private syntax only in classes, this may not 
matter. Either private symbols or weak maps suffice. But proxies can 
tell, and prototype-based inheritance works for private symbols but not 
weak maps.


So even if we allow a frozen object to grow new private-symbol-keyed 
properties not in that object at the time it was frozen (or let's say 
the time Object.preventExtensions or its internal form was invoked), 
private symbols and weak maps are distinguishable. If they weren't, we 
surely would have no need for one or the other.


/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-19 Thread Allen Wirfs-Brock

On Jan 19, 2013, at 11:39 AM, Brendan Eich wrote:

> Something was nagging me from the 2011-era debate over private symbols vs. 
> weak maps, and that's the ability of a weak map to implement soft fields on 
> frozen objects. Symbols (private or not) can't do that.
> 
> Not sure this matters in the current proxy-focused thread, but I thought I 
> would point it out explicitly.

It seems like at the root of this question revolves around what you mean by a 
"frozen object".  

In ES5 there is no such concept.  There really is only the 
Object.freeze/Object.isFrozen functions.  These are defined operationally in 
terms of specific constructs that exist in ES5.  There really is no guidance in 
those definitions as to how they should be extended when when new constructs 
are added to the language.

Also, the effect obtained by applying Object.freeze to an object isn't a 
fundamental characteristic of an object.  The exact same effect can be achieve 
by a combination of other calls and Object.isFreeze will still report true.

Who's to say that a symbol keyed object can't be added to an object after 
Object.freeze has been applied to it.  Before we can say that we have to define 
the semantics of symbol keyed objects and possibly extend 
Object.freeze/isFrozen to accommodate those new semantics. What's the guidance 
for doing so?  What abstract concept of "frozen" do we to apply to the 
semantics of new language features?

Allen


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


Re: Security Demands Simplicity (was: Private Slots)

2013-01-19 Thread Brendan Eich
Something was nagging me from the 2011-era debate over private symbols 
vs. weak maps, and that's the ability of a weak map to implement soft 
fields on frozen objects. Symbols (private or not) can't do that.


Not sure this matters in the current proxy-focused thread, but I thought 
I would point it out explicitly.


/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-19 Thread David Bruant

Le 19/01/2013 19:04, Kevin Smith a écrit :



It calls the unknownPrivateSymbol trap. If the trap throws, the
operation fails. In all other cases (no trap or trap which doesn't
throw), it's forwarded.


And can frozen objects be proxy targets, or no?

Yes they can.

More generally, can a proxy effectively override the behavior of a 
non-configurable, non-writable property on the target?


var target = Object.create(null, { foo: { writable: false, 
configurable: false, value: 1 } });


var proxy = new Proxy(target, {
  get(obj, name) { return name === "foo" ? 0 : obj[name]; }
});

console.log(target.foo); // 1
console.log(proxy.foo); // 0

This this allowed?
It is not. At the exit of the get trap, the JS engine checks whether 
invariants should be enforced for the given property on the target. In 
your case, the runtime sees that the target has a non-configurable 
non-writable property called 'foo' with 1 as value. When you try to 
return 0, it will throw a TypeError because of invariant violation. You 
can read about invariants at 
http://wiki.ecmascript.org/doku.php?id=harmony:direct_proxies#invariant_enforcement


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


Re: Security Demands Simplicity (was: Private Slots)

2013-01-19 Thread Kevin Smith
>
>
> It calls the unknownPrivateSymbol trap. If the trap throws, the operation
> fails. In all other cases (no trap or trap which doesn't throw), it's
> forwarded.
>

And can frozen objects be proxy targets, or no?  More generally, can a
proxy effectively override the behavior of a non-configurable, non-writable
property on the target?

var target = Object.create(null, { foo: { writable: false,
configurable: false, value: 1 } });

var proxy = new Proxy(target, {
  get(obj, name) { return name === "foo" ? 0 : obj[name]; }
});

console.log(target.foo); // 1
console.log(proxy.foo); // 0

This this allowed?

{ Kevin }
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-19 Thread David Bruant

Le 19/01/2013 16:30, Kevin Smith a écrit :


The interaction between private syntax and proxies has the
following components:
1) Do the proxy and the target act the same regarding private
properties?
The answer is yes with whitelisted private symbols, no with naive
weakmap-expanded private syntax (I explain non-naive below)


What happens if the private symbol is not on the whitelist?  Does the 
private symbol get/set operation get forwarded to the target, or does 
it fail?
It calls the unknownPrivateSymbol trap. If the trap throws, the 
operation fails. In all other cases (no trap or trap which doesn't 
throw), it's forwarded.
I made the assumption that private syntax result in whitelisted symbols 
and that's actually a non-trivial assumption... hmm... it's actually a 
false assumption. Somehow, the private symbols generated from private 
syntax would need to be exposed by the class or something to be added to 
the whitelist set when a proxy wants to transparently wrap class 
instances. This would force to violate the class encapsulation.
This means that for proxies to work with class instances, private syntax 
has to expand to something else than private symbols. WeakMap being 
first choice obviously and the necessity of private symbols become more 
and more questionable.



(Sorry for the remedial question.)

No worries. Sorry for being too quick in my explanations ;-)

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


Re: Security Demands Simplicity (was: Private Slots)

2013-01-19 Thread Kevin Smith
> The interaction between private syntax and proxies has the following
> components:
> 1) Do the proxy and the target act the same regarding private properties?
> The answer is yes with whitelisted private symbols, no with naive
> weakmap-expanded private syntax (I explain non-naive below)
>

What happens if the private symbol is not on the whitelist?  Does the
private symbol get/set operation get forwarded to the target, or does it
fail?  (Sorry for the remedial question.)

{ Kevin }
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-18 Thread Kevin Smith
I've been stewing on this some more, and I realized something potentially
> very interesting. If we use weakmaps in the manner specified by Kevin (with
> Mark's help),


Um, that should be "Mark (with Kevin's itty-bitty help)".  : )

{ Kevin }
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-18 Thread Kevin Smith
>
> Kevin, could you do an alterna-gist as Domenic proposes? Of course there's
> much more at stake than syntax, but it would help.
>

I've updated my gist to clarify Domenic's second point, but I'll let him
maintain his fork for the "@" syntax variation.

{ Kevin }
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-18 Thread David Bruant

Le 18/01/2013 06:47, Russell Leggett a écrit :
On Thu, Jan 17, 2013 at 9:40 PM, Kevin Smith > wrote:


It seems as if this approach to private class members also allows
us to describe private methods in a convenient way.  Private
methods can be attached to the _prototype_ of the private field
object, thus avoiding per-instance allocation.  Of course, the
correct "this" value has to be used in the expansion when calling
the private method, but this approach appears to be compatible
with mixins (whereas private symbols are not).

https://gist.github.com/4561871

Thoughts?


I've been on the fence with the debate, but I'll admit that this 
proposal is really winning me over. I don't know if it's too late to 
get this syntax in, but it would be a major win for me.

syntax details aside (especially with Domenic improvements), I agree.


I like this a lot more than private symbols.

Assuming the only valid use case for private symbols is classes, I agree

It actually feels a lot like deconstructing an abstract data type or 
pattern matching a case class in scala. There is something nice about 
keeping all that extra stuff off the actual object. I'm not sure if 
I'd still like it as much without the syntax, but maybe I would now.


I have do have a few questions on this, though:

1. How does this interact with proxies? I'm guessing that a proxy will 
not map correctly and therefore make it inaccessible. Personally, I'm 
ok with that.
It does not interact that well because of the this-binding. Classes have 
been long expected, so will be used, so proxies have to work well with them.


class Purse {
private balance;

constructor(balance = 0) {
private.balance = balance;
}

 getBalance() { return balance; }
}

var p = new Purse(6);
var pp = new Proxy(p, {});
console.log(pp.getBalance());

We should be able to expect p and pp to act the same in all 
circumstances. With Kevin's expansion, pp.getBalance() throws a 
TypeError, because "amp.get(this)" is not an object.
Proxy authors can work around that by returning functions bound to the 
target, but this is not free obviously (create as much bound functions 
as there are of (instance, method) pair).


The interaction between private syntax and proxies has the following 
components:

1) Do the proxy and the target act the same regarding private properties?
The answer is yes with whitelisted private symbols, no with naive 
weakmap-expanded private syntax (I explain non-naive below)

I think the answer should be yes here.

2) Does the proxy has a word to say about the access to the private 
property?

It's yes with private symbols (different trap if whitelisted or not).
The answer is yes for weakmap-expanded private syntax, but with some 
explanation. The proxy can't know about the private property, however, 
every access to something private has to be performed through something 
public (public accessor or method). Indeed, the class encapsulate access 
to private state (this isn't true of private symbols in general). Since 
the proxy can cut communication of public accesses, it can also cut 
accesses to private properties. I think that this additional simplicity 
weighs in favor of the removal of private symbols.


(I had a third point in mind and I forgot it...)


Above I've talked about naive weakmap-expanded private syntax. A less 
naive version could "override" the Proxy constructor to know about proxy 
-> target associations. Access to private state wouldn't start with the 
naive "amp.get(this)", but rather with "amp.get(proxyToFinalTarget(this) 
|| this)". ("finalTarget" in case the target of the proxy is itself a 
proxy).
For native syntax, we can imagine this setup exists before any code 
runs. The transpiler story is a bit less clear to me. I see different 
ways of writing class transpilers with different properties:

1) make classes incompatible with proxies
2) share (aka "leak") the proxyToFinalTarget function to transpiled classes
3) bring the full transpiler in the runtime so that classes can work 
with proxies (only the transpiler has access to proxyToFinalTarget)
I think different users in different contexts all have a solution to 
their need.


2. Can I use private as a normal variable? Can it be bound to a new 
variable, passed as an argument, or returned from a function?

constructor(balance = 0) {
let p = private;
p.checkNum(amount);
p.balance = balance;
}
I would understand not going this route, but it definitely restricts 
access very tightly where private member or manually using a weakmap 
would allow it. Perhaps that edge case can just be handled by falling 
back to manually using a weakmap.
Mark's point about private symbol being mostly useful in the context of 
class convinced me that pretty much every other context can work with 
WeakMaps.


No opinion on your third point.

David

Re: Security Demands Simplicity (was: Private Slots)

2013-01-18 Thread Russell Leggett
I've been stewing on this some more, and I realized something potentially
very interesting. If we use weakmaps in the manner specified by Kevin (with
Mark's help), I think we've very nearly added nominal typing to classes.
Assuming this privacy behavior was tied to classes, and assuming only
members of the class could be added to the weakmap, and assuming that *all*
members of the class belonged to the weakmap, the weakmap would quite
literally be the set of all members of that class (type). If there was an
easy way of asking the weakmap if an object belonged to the it, it would
the same as asking if the object was an instance of that class in a very
strong, nominal way. I guess I think this could be a plus, because it
allows for nominal types to be tied to classes, and yet do it in a very
javascripty feeling way.

Thoughts?

- Russ

On Fri, Jan 18, 2013 at 4:25 AM, Brendan Eich  wrote:

> Domenic Denicola wrote:
>
>>
>> If we’re making up new syntax, I think this would be much nicer if
>> “private.x” were spelled “this.@x” and “private(x)” were spelled “x.@”
>>
>>
> +1 and this is not a minor point.
>
>
>  Also, I don’t see why constructors need to use the “private.x” syntax
>> whereas other methods get to use the free variable?
>>
>>
> +2 -- Same here, only moreso!
>
> This thread goes over ground well-trod in 2011:
>
> https://mail.mozilla.org/**pipermail/es-discuss/2011-**July/015787.html<https://mail.mozilla.org/pipermail/es-discuss/2011-July/015787.html>
>
> and others -- search for "private data record" 2011 es-discuss site:
> mail.mozilla.org.
>
>
>  With these in mind I give the following fork: https://gist.github.com/**
>> 4562796 <https://gist.github.com/4562796>
>>
>>
> Kevin, could you do an alterna-gist as Domenic proposes? Of course there's
> much more at stake than syntax, but it would help.
>
> /be
>
>>
>> *From:*es-discuss-bounces@**mozilla.org 
>> [mailto:
>> es-discuss-bounces@**mozilla.org ] *On
>> Behalf Of *Kevin Smith
>> *Sent:* Thursday, January 17, 2013 21:40
>> *To:* Mark S. Miller
>> *Cc:* Brendan Eich; es-discuss
>> *Subject:* Re: Security Demands Simplicity (was: Private Slots)
>>
>>
>> It seems as if this approach to private class members also allows us to
>> describe private methods in a convenient way.  Private methods can be
>> attached to the _prototype_ of the private field object, thus avoiding
>> per-instance allocation.  Of course, the correct "this" value has to be
>> used in the expansion when calling the private method, but this approach
>> appears to be compatible with mixins (whereas private symbols are not).
>>
>> https://gist.github.com/**4561871 <https://gist.github.com/4561871>
>>
>> Thoughts?
>>
>> { Kevin }
>>
>>  __**_
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/**listinfo/es-discuss<https://mail.mozilla.org/listinfo/es-discuss>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-18 Thread Brendan Eich

Domenic Denicola wrote:


If we’re making up new syntax, I think this would be much nicer if 
“private.x” were spelled “this.@x” and “private(x)” were spelled “x.@”




+1 and this is not a minor point.

Also, I don’t see why constructors need to use the “private.x” syntax 
whereas other methods get to use the free variable?




+2 -- Same here, only moreso!

This thread goes over ground well-trod in 2011:

https://mail.mozilla.org/pipermail/es-discuss/2011-July/015787.html

and others -- search for "private data record" 2011 es-discuss 
site:mail.mozilla.org.


With these in mind I give the following fork: 
https://gist.github.com/4562796




Kevin, could you do an alterna-gist as Domenic proposes? Of course 
there's much more at stake than syntax, but it would help.


/be


*From:*es-discuss-boun...@mozilla.org 
[mailto:es-discuss-boun...@mozilla.org] *On Behalf Of *Kevin Smith

*Sent:* Thursday, January 17, 2013 21:40
*To:* Mark S. Miller
*Cc:* Brendan Eich; es-discuss
*Subject:* Re: Security Demands Simplicity (was: Private Slots)

It seems as if this approach to private class members also allows us 
to describe private methods in a convenient way.  Private methods can 
be attached to the _prototype_ of the private field object, thus 
avoiding per-instance allocation.  Of course, the correct "this" value 
has to be used in the expansion when calling the private method, but 
this approach appears to be compatible with mixins (whereas private 
symbols are not).


https://gist.github.com/4561871

Thoughts?

{ Kevin }


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


Re: Security Demands Simplicity (was: Private Slots)

2013-01-17 Thread Kevin Smith
>
>
> Also, I don’t see why constructors need to use the “private.x” syntax
> whereas other methods get to use the free variable?
>

They wouldn't.  I was just trying to show the different ways to do the same
thing.


> 
>
> ** **
>
> With these in mind I give the following fork:
> https://gist.github.com/4562796
>

Cool variation!  We still might want to use @ for (unique) symbols
though...  (?)  Also, "private" makes it clear we are dealing with a
separate (although intimately related) object.

{ Kevin }
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


RE: Security Demands Simplicity (was: Private Slots)

2013-01-17 Thread Domenic Denicola
If we’re making up new syntax, I think this would be much nicer if “private.x” 
were spelled “this.@x” and “private(x)” were spelled “x.@”

Also, I don’t see why constructors need to use the “private.x” syntax whereas 
other methods get to use the free variable?

With these in mind I give the following fork: https://gist.github.com/4562796

From: es-discuss-boun...@mozilla.org [mailto:es-discuss-boun...@mozilla.org] On 
Behalf Of Kevin Smith
Sent: Thursday, January 17, 2013 21:40
To: Mark S. Miller
Cc: Brendan Eich; es-discuss
Subject: Re: Security Demands Simplicity (was: Private Slots)

It seems as if this approach to private class members also allows us to 
describe private methods in a convenient way.  Private methods can be attached 
to the _prototype_ of the private field object, thus avoiding per-instance 
allocation.  Of course, the correct "this" value has to be used in the 
expansion when calling the private method, but this approach appears to be 
compatible with mixins (whereas private symbols are not).

https://gist.github.com/4561871

Thoughts?

{ Kevin }
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-17 Thread Russell Leggett
On Thu, Jan 17, 2013 at 9:40 PM, Kevin Smith  wrote:

> It seems as if this approach to private class members also allows us to
> describe private methods in a convenient way.  Private methods can be
> attached to the _prototype_ of the private field object, thus avoiding
> per-instance allocation.  Of course, the correct "this" value has to be
> used in the expansion when calling the private method, but this approach
> appears to be compatible with mixins (whereas private symbols are not).
>
> https://gist.github.com/4561871
>
> Thoughts?
>

I've been on the fence with the debate, but I'll admit that this proposal
is really winning me over. I don't know if it's too late to get this syntax
in, but it would be a major win for me. I like this a lot more than private
symbols. It actually feels a lot like deconstructing an abstract data type
or pattern matching a case class in scala. There is something nice about
keeping all that extra stuff off the actual object. I'm not sure if I'd
still like it as much without the syntax, but maybe I would now.

I have do have a few questions on this, though:

1. How does this interact with proxies? I'm guessing that a proxy will not
map correctly and therefore make it inaccessible. Personally, I'm ok with
that.

2. Can I use private as a normal variable? Can it be bound to a new
variable, passed as an argument, or returned from a function?
constructor(balance = 0) {
let p = private;
p.checkNum(amount);
p.balance = balance;
}
I would understand not going this route, but it definitely restricts access
very tightly where private member or manually using a weakmap would allow
it. Perhaps that edge case can just be handled by falling back to manually
using a weakmap. I admit its a pretty narrow case, and perhaps is best to
not be easy to do. If it *were* to be allowed to be passed around, the
shorthand accessor syntax wouldn't work unless you captured the "this" as
part of the assignment. Definitely possible, though.

3. Can private() be used to add arbitrary object to the map even if they
don't belong to the class?
let obj = {};
private(obj).balance = 10;
I'm guessing not, as it translates to a get right now, but curious if this
was a consideration.

- Russ



>
> { Kevin }
>
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-17 Thread Kevin Smith
It seems as if this approach to private class members also allows us to
describe private methods in a convenient way.  Private methods can be
attached to the _prototype_ of the private field object, thus avoiding
per-instance allocation.  Of course, the correct "this" value has to be
used in the expansion when calling the private method, but this approach
appears to be compatible with mixins (whereas private symbols are not).

https://gist.github.com/4561871

Thoughts?

{ Kevin }
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-17 Thread Mark S. Miller
On Thu, Jan 17, 2013 at 1:50 PM, Mark S. Miller  wrote:
> On Thu, Jan 17, 2013 at 1:13 PM, David Bruant  wrote:
>> Le 17/01/2013 19:30, Mark S. Miller a écrit :
>>>
>>> 2) Until ES7 provides private
>>
>> I may have missed something. In the harmony proposal on the wiki [1] (is the
>> wiki down? I'm looking at google's cache),
>
> I don't know, but seems down for me too. But the classes accepted for
> ES6 are "maximally minimal" and contain no field declarations of any
> kind.

Back up. Maximin is at




>
>> I see that syntax for private
>> properties is in the proposal and nothing suggests it's postpone until ES7.
>> I see in recent notes that the @-syntax isn't fully agreed upon, but that's
>> where I'm at. Is there no private syntax at all for classes in ES6?
>
> Correct.
>
>
>>
>>
>>> there will be transpilers that provide actual privacy by other means.
>>
>> What syntax and semantics will these transpilers use if TC39 doesn't reach
>> an agreement?
>>
>>
>>> 3) Most important, and most unsaid by my previous email: In ES6, since
>>> there's no built-in class/object privacy mechanism, ES6 programmers in
>>> general and ES6 class programmers specifically have to achieve real
>>> privacy by other means -- by engaging in some pattern using other
>>> constructs. Previous conversations assumed that these patterns would
>>> be expressed in terms of private symbols. Absent private symbols, the
>>> pattern shown by my expansion above, as painful as it is, is what will
>>> be expressed manually. By the time ES7 rolls out, there will be a lot
>>> of that code.
>>
>> People who care will use a transpiler (and I personally don't care if the
>> generated code is slightly slower than what it could be natively or ugly).
>> People who don't care about privacy will go on with their lives writing
>> JavaScript as they do in ES5.
>> That's an ephemeral problem in my opinion and isn't the "most important"
>> point. Am I underestimating it?
>
> I believe you are. For abstractions with small numbers of methods and
> no interesting inheritance, I find the objects-as-closures pattern +
> weakmaps for class-private instance variables, as in our recent paper,
> to be more pleasant than the likely ES7 class syntax anyway; and much
> simpler to understand. And it's way more pleasant than the maximin
> classes accepted for ES6. We will see a lot of code manually using
> WeakMaps in this way.
>
>
>>
>> David
>>
>> [1] http://wiki.ecmascript.org/doku.php?id=harmony:classes
>
>
>
> --
> Cheers,
> --MarkM



--
Cheers,
--MarkM
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-17 Thread Brandon Benvie
November's meeting had re-instituted computed property names to compensate
for the dropping @name support to allow for symbols to be used as method
names. AFAICT there's currently no actual way to create a private Symbol in
any active proposals for ES6, however (this was only covered as part of the
@names proposal). Currently `Symbol` only accepts one parameter, and that's
the string label/name for it.


On Thu, Jan 17, 2013 at 4:13 PM, David Bruant  wrote:

> Le 17/01/2013 19:30, Mark S. Miller a écrit :
>
>> On Thu, Jan 17, 2013 at 10:02 AM, David Bruant 
>> wrote:
>>
>>> Le 17/01/2013 18:00, Mark S. Miller a écrit :
>>>
 I still have this position on classes. But I no longer buy that

 pessimistic conclusion about WeakMaps. Consider how WeakMaps would be
 used by the expansion of classes-with-private. Just 'cause it's on the
 top of my head, below I use the old representation of one WeakMap per
 class providing access to a record of all the private state. For the
 same reason, I'll use the encapsulation of the Purse example without
 any of the numeric checks.

 class Purse {
   constructor(private balance) {
   getBalance() { return balance; }
   makePurse() { return Purse(0); }
   deposit(amount, srcPurse) {
   private(srcPurse).balance -= amount;
   balance += amount;
   }
 }

 expansion

>>> I don't understand the need to expand. This is the class syntax. It
>>> creates
>>> a constructor. Instances of this constructor have some behavior and
>>> characteristics described by the class body. If the class body allows to
>>> define something private, implementors will implement that and work very
>>> hard on performance. I don't think implementors will expand before
>>> compiling
>>> and using the class syntax as some sort of macro (implementors are free
>>> to
>>> tell I'm wrong here).
>>> Assuming I'm right, what it expands to exactly does not matter much,
>>> whether
>>> it's private name or weakmaps or whatever else.
>>>
>> Regarding what I actually said, you're right. I am being unbelievable
>> confusing this morning. After that sleepless night, I should probably
>> wait till I'm rested before posting again. Foolishly perhaps, I'll try
>> to answer anyway.
>>
>>
>> 1) It remains useful to define the semantics of classes by expansion.
>> Then one can reason about classes by reasoning about the expansion.
>> This is especially helpful for automated tools. The semantics had then
>> better be faithful to the explanatory expansion.
>>
>> 2) Until ES7 provides private
>>
> I may have missed something. In the harmony proposal on the wiki [1] (is
> the wiki down? I'm looking at google's cache), I see that syntax for
> private properties is in the proposal and nothing suggests it's postpone
> until ES7. I see in recent notes that the @-syntax isn't fully agreed upon,
> but that's where I'm at. Is there no private syntax at all for classes in
> ES6?
>
>
>  there will be transpilers that provide actual privacy by other means.
>>
> What syntax and semantics will these transpilers use if TC39 doesn't reach
> an agreement?
>
>
>  3) Most important, and most unsaid by my previous email: In ES6, since
>> there's no built-in class/object privacy mechanism, ES6 programmers in
>> general and ES6 class programmers specifically have to achieve real
>> privacy by other means -- by engaging in some pattern using other
>> constructs. Previous conversations assumed that these patterns would
>> be expressed in terms of private symbols. Absent private symbols, the
>> pattern shown by my expansion above, as painful as it is, is what will
>> be expressed manually. By the time ES7 rolls out, there will be a lot
>> of that code.
>>
> People who care will use a transpiler (and I personally don't care if the
> generated code is slightly slower than what it could be natively or ugly).
> People who don't care about privacy will go on with their lives writing
> JavaScript as they do in ES5.
> That's an ephemeral problem in my opinion and isn't the "most important"
> point. Am I underestimating it?
>
> David
>
> [1] 
> http://wiki.ecmascript.org/**doku.php?id=harmony:classes
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-17 Thread Mark S. Miller
On Thu, Jan 17, 2013 at 1:13 PM, David Bruant  wrote:
> Le 17/01/2013 19:30, Mark S. Miller a écrit :
>>
>> 2) Until ES7 provides private
>
> I may have missed something. In the harmony proposal on the wiki [1] (is the
> wiki down? I'm looking at google's cache),

I don't know, but seems down for me too. But the classes accepted for
ES6 are "maximally minimal" and contain no field declarations of any
kind.

> I see that syntax for private
> properties is in the proposal and nothing suggests it's postpone until ES7.
> I see in recent notes that the @-syntax isn't fully agreed upon, but that's
> where I'm at. Is there no private syntax at all for classes in ES6?

Correct.


>
>
>> there will be transpilers that provide actual privacy by other means.
>
> What syntax and semantics will these transpilers use if TC39 doesn't reach
> an agreement?
>
>
>> 3) Most important, and most unsaid by my previous email: In ES6, since
>> there's no built-in class/object privacy mechanism, ES6 programmers in
>> general and ES6 class programmers specifically have to achieve real
>> privacy by other means -- by engaging in some pattern using other
>> constructs. Previous conversations assumed that these patterns would
>> be expressed in terms of private symbols. Absent private symbols, the
>> pattern shown by my expansion above, as painful as it is, is what will
>> be expressed manually. By the time ES7 rolls out, there will be a lot
>> of that code.
>
> People who care will use a transpiler (and I personally don't care if the
> generated code is slightly slower than what it could be natively or ugly).
> People who don't care about privacy will go on with their lives writing
> JavaScript as they do in ES5.
> That's an ephemeral problem in my opinion and isn't the "most important"
> point. Am I underestimating it?

I believe you are. For abstractions with small numbers of methods and
no interesting inheritance, I find the objects-as-closures pattern +
weakmaps for class-private instance variables, as in our recent paper,
to be more pleasant than the likely ES7 class syntax anyway; and much
simpler to understand. And it's way more pleasant than the maximin
classes accepted for ES6. We will see a lot of code manually using
WeakMaps in this way.


>
> David
>
> [1] http://wiki.ecmascript.org/doku.php?id=harmony:classes



--
Cheers,
--MarkM
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-17 Thread Kevin Smith
>
> The Ephemeron gc technique
> contributes nothing to the ability to reclaim space for such code
> because of the relative lifetimes of the map and its keys.
>

Yes - my line-of-thought as well.  If I may riff on your code a bit (ymmv):

class Purse {

// Move private field declaration out here for more scopy-ness
private balance;

// Allow private without arg as shorthand for "private(this)"
constructor(balance = 0) { private.balance = balance; }

// Everything else the same
getBalance() { return balance; }
makePurse() { return new Purse; }
deposit(amount, srcPurse) {
private(srcPurse).balance -= amount;
balance += amount;
}
}

The expansion is exactly the same, except that the private record is sealed
before the constructor body starts executing.  Reconceptualizing private
instance state in terms of a separate object stored in a weakmap -
interesting!

{ Kevin }
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-17 Thread David Bruant

Le 17/01/2013 19:30, Mark S. Miller a écrit :

On Thu, Jan 17, 2013 at 10:02 AM, David Bruant  wrote:

Le 17/01/2013 18:00, Mark S. Miller a écrit :

I still have this position on classes. But I no longer buy that
pessimistic conclusion about WeakMaps. Consider how WeakMaps would be
used by the expansion of classes-with-private. Just 'cause it's on the
top of my head, below I use the old representation of one WeakMap per
class providing access to a record of all the private state. For the
same reason, I'll use the encapsulation of the Purse example without
any of the numeric checks.

class Purse {
  constructor(private balance) {
  getBalance() { return balance; }
  makePurse() { return Purse(0); }
  deposit(amount, srcPurse) {
  private(srcPurse).balance -= amount;
  balance += amount;
  }
}

expansion

I don't understand the need to expand. This is the class syntax. It creates
a constructor. Instances of this constructor have some behavior and
characteristics described by the class body. If the class body allows to
define something private, implementors will implement that and work very
hard on performance. I don't think implementors will expand before compiling
and using the class syntax as some sort of macro (implementors are free to
tell I'm wrong here).
Assuming I'm right, what it expands to exactly does not matter much, whether
it's private name or weakmaps or whatever else.

Regarding what I actually said, you're right. I am being unbelievable
confusing this morning. After that sleepless night, I should probably
wait till I'm rested before posting again. Foolishly perhaps, I'll try
to answer anyway.


1) It remains useful to define the semantics of classes by expansion.
Then one can reason about classes by reasoning about the expansion.
This is especially helpful for automated tools. The semantics had then
better be faithful to the explanatory expansion.

2) Until ES7 provides private
I may have missed something. In the harmony proposal on the wiki [1] (is 
the wiki down? I'm looking at google's cache), I see that syntax for 
private properties is in the proposal and nothing suggests it's postpone 
until ES7. I see in recent notes that the @-syntax isn't fully agreed 
upon, but that's where I'm at. Is there no private syntax at all for 
classes in ES6?



there will be transpilers that provide actual privacy by other means.
What syntax and semantics will these transpilers use if TC39 doesn't 
reach an agreement?



3) Most important, and most unsaid by my previous email: In ES6, since
there's no built-in class/object privacy mechanism, ES6 programmers in
general and ES6 class programmers specifically have to achieve real
privacy by other means -- by engaging in some pattern using other
constructs. Previous conversations assumed that these patterns would
be expressed in terms of private symbols. Absent private symbols, the
pattern shown by my expansion above, as painful as it is, is what will
be expressed manually. By the time ES7 rolls out, there will be a lot
of that code.
People who care will use a transpiler (and I personally don't care if 
the generated code is slightly slower than what it could be natively or 
ugly). People who don't care about privacy will go on with their lives 
writing JavaScript as they do in ES5.
That's an ephemeral problem in my opinion and isn't the "most important" 
point. Am I underestimating it?


David

[1] http://wiki.ecmascript.org/doku.php?id=harmony:classes
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-17 Thread Mark Miller
I just looked back at the example code in "Distributed Electronic Rights in
JavaScript". It uses WeakMaps in two places: Fig1 line2 and Fig3 line2.
Both of these express objects using the objects-as-closures pattern, not
using classes. It's clearly affordable here since there are only 3 and 2
methods respectively. In both of these, the use of WeakMap has the lifetime
properties I point out -- the weakmap's keys can never outlive the weakmap.
The pattern, as you see there, expressed manually without any classes, is
syntactically quite pleasant. Implementations that use Ephemeron gc
techniques to implement these weakmaps will be outperformed by
implementations that simply hang the private value state off of the key
object. These manual uses of WeakMap would use the hint if such a hint
existed.


On Thu, Jan 17, 2013 at 10:30 AM, Mark S. Miller  wrote:

> On Thu, Jan 17, 2013 at 10:02 AM, David Bruant  wrote:
> > Le 17/01/2013 18:00, Mark S. Miller a écrit :
> >
> >> However, after the "Private Slots" thread, I spent a sleepless night
> >> chewing on getting rid of private symbols.
> >
> > Happens to me so often :-)
> >
> >
> >> I now think we should.
> >> Going back to my earlier
> >>
> >>
> >> On Wed, Jan 16, 2013 at 12:37 PM, Mark S. Miller 
> >> wrote:
> >>>
> >>> My position on private symbols.
> >>>
> >>> My position on classes is and has always been that classes are worth
> >>> introducing into the language *only* if they give us, or can be used
> >>> with, an affordable means for true object encapsulation. Assuming
> >>> Allen is right about what actual implementors will do (which I find
> >>> plausible) then WeakMaps are not that means.
> >>
> >> I still have this position on classes. But I no longer buy that
> >> pessimistic conclusion about WeakMaps. Consider how WeakMaps would be
> >> used by the expansion of classes-with-private. Just 'cause it's on the
> >> top of my head, below I use the old representation of one WeakMap per
> >> class providing access to a record of all the private state. For the
> >> same reason, I'll use the encapsulation of the Purse example without
> >> any of the numeric checks.
> >>
> >> class Purse {
> >>  constructor(private balance) {
> >>  getBalance() { return balance; }
> >>  makePurse() { return Purse(0); }
> >>  deposit(amount, srcPurse) {
> >>  private(srcPurse).balance -= amount;
> >>  balance += amount;
> >>  }
> >> }
> >>
> >> expansion
> >
> > I don't understand the need to expand. This is the class syntax. It
> creates
> > a constructor. Instances of this constructor have some behavior and
> > characteristics described by the class body. If the class body allows to
> > define something private, implementors will implement that and work very
> > hard on performance. I don't think implementors will expand before
> compiling
> > and using the class syntax as some sort of macro (implementors are free
> to
> > tell I'm wrong here).
> > Assuming I'm right, what it expands to exactly does not matter much,
> whether
> > it's private name or weakmaps or whatever else.
>
> Regarding what I actually said, you're right. I am being unbelievable
> confusing this morning. After that sleepless night, I should probably
> wait till I'm rested before posting again. Foolishly perhaps, I'll try
> to answer anyway.
>
>
> 1) It remains useful to define the semantics of classes by expansion.
> Then one can reason about classes by reasoning about the expansion.
> This is especially helpful for automated tools. The semantics had then
> better be faithful to the explanatory expansion.
>
> 2) Until ES7 provides private, there will be transpilers that provide
> actual privacy by other means.
>
> 3) Most important, and most unsaid by my previous email: In ES6, since
> there's no built-in class/object privacy mechanism, ES6 programmers in
> general and ES6 class programmers specifically have to achieve real
> privacy by other means -- by engaging in some pattern using other
> constructs. Previous conversations assumed that these patterns would
> be expressed in terms of private symbols. Absent private symbols, the
> pattern shown by my expansion above, as painful as it is, is what will
> be expressed manually. By the time ES7 rolls out, there will be a lot
> of that code.
>
>
>
> >
> > Now you're only talking about privacy in the context of classes in this
> > post. I understand this as assuming private symbols would be only use in
> > class or class-like contexts (after referred as "this assumption" or "the
> > assumption").
> > If that's your assumption, then I agree that if classes have a "private"
> > syntax that is efficiently compiled, private symbols can be dropped.
> > It has to be noted that if private symbols are dropped, the set of
> private
> > properties is sealed once and for all in the class body. That is, it's
> not
> > possible to add or remove a private property after initialization.
> (However
> > it remains possible to privately att

Re: Security Demands Simplicity (was: Private Slots)

2013-01-17 Thread Mark S. Miller
On Thu, Jan 17, 2013 at 10:02 AM, David Bruant  wrote:
> Le 17/01/2013 18:00, Mark S. Miller a écrit :
>
>> However, after the "Private Slots" thread, I spent a sleepless night
>> chewing on getting rid of private symbols.
>
> Happens to me so often :-)
>
>
>> I now think we should.
>> Going back to my earlier
>>
>>
>> On Wed, Jan 16, 2013 at 12:37 PM, Mark S. Miller 
>> wrote:
>>>
>>> My position on private symbols.
>>>
>>> My position on classes is and has always been that classes are worth
>>> introducing into the language *only* if they give us, or can be used
>>> with, an affordable means for true object encapsulation. Assuming
>>> Allen is right about what actual implementors will do (which I find
>>> plausible) then WeakMaps are not that means.
>>
>> I still have this position on classes. But I no longer buy that
>> pessimistic conclusion about WeakMaps. Consider how WeakMaps would be
>> used by the expansion of classes-with-private. Just 'cause it's on the
>> top of my head, below I use the old representation of one WeakMap per
>> class providing access to a record of all the private state. For the
>> same reason, I'll use the encapsulation of the Purse example without
>> any of the numeric checks.
>>
>> class Purse {
>>  constructor(private balance) {
>>  getBalance() { return balance; }
>>  makePurse() { return Purse(0); }
>>  deposit(amount, srcPurse) {
>>  private(srcPurse).balance -= amount;
>>  balance += amount;
>>  }
>> }
>>
>> expansion
>
> I don't understand the need to expand. This is the class syntax. It creates
> a constructor. Instances of this constructor have some behavior and
> characteristics described by the class body. If the class body allows to
> define something private, implementors will implement that and work very
> hard on performance. I don't think implementors will expand before compiling
> and using the class syntax as some sort of macro (implementors are free to
> tell I'm wrong here).
> Assuming I'm right, what it expands to exactly does not matter much, whether
> it's private name or weakmaps or whatever else.

Regarding what I actually said, you're right. I am being unbelievable
confusing this morning. After that sleepless night, I should probably
wait till I'm rested before posting again. Foolishly perhaps, I'll try
to answer anyway.


1) It remains useful to define the semantics of classes by expansion.
Then one can reason about classes by reasoning about the expansion.
This is especially helpful for automated tools. The semantics had then
better be faithful to the explanatory expansion.

2) Until ES7 provides private, there will be transpilers that provide
actual privacy by other means.

3) Most important, and most unsaid by my previous email: In ES6, since
there's no built-in class/object privacy mechanism, ES6 programmers in
general and ES6 class programmers specifically have to achieve real
privacy by other means -- by engaging in some pattern using other
constructs. Previous conversations assumed that these patterns would
be expressed in terms of private symbols. Absent private symbols, the
pattern shown by my expansion above, as painful as it is, is what will
be expressed manually. By the time ES7 rolls out, there will be a lot
of that code.



>
> Now you're only talking about privacy in the context of classes in this
> post. I understand this as assuming private symbols would be only use in
> class or class-like contexts (after referred as "this assumption" or "the
> assumption").
> If that's your assumption, then I agree that if classes have a "private"
> syntax that is efficiently compiled, private symbols can be dropped.
> It has to be noted that if private symbols are dropped, the set of private
> properties is sealed once and for all in the class body. That is, it's not
> possible to add or remove a private property after initialization. (However
> it remains possible to privately attach information to an object with a
> weakmap kept private)
>
> If "private symbols will be only used in class or class-like contexts" is
> your assumption, let's talk about it. Historically, JavaScript objects have
> been used in both in OO contexts and as maps. This confusion led to some
> bugs (involving __proto__ for instance)
> As I have suggested in another recent post, most of the time, objects in OO
> contexts are pretty stable: they are created with a given set of properties
> which doesn't change. This stability could even be declared statically
> (that's what the class syntax does actually).
> However, for the map use case, it makes sense to add and remove properties
> at runtime.
>
> ES6 adds actual maps, so objects (especially the ones instanciated after
> class-born constructors) could be legitimately considered as reserved for OO
> contexts.
> That's a reasoning I agree with since I can't think of cases besides classes
> where private symbols would be used and for which weakmaps wouldn't be
> better.
>
> So I guess I agr

Re: Security Demands Simplicity (was: Private Slots)

2013-01-17 Thread David Bruant

Le 17/01/2013 18:00, Mark S. Miller a écrit :

However, after the "Private Slots" thread, I spent a sleepless night
chewing on getting rid of private symbols.

Happens to me so often :-)


I now think we should.
Going back to my earlier


On Wed, Jan 16, 2013 at 12:37 PM, Mark S. Miller  wrote:

My position on private symbols.

My position on classes is and has always been that classes are worth
introducing into the language *only* if they give us, or can be used
with, an affordable means for true object encapsulation. Assuming
Allen is right about what actual implementors will do (which I find
plausible) then WeakMaps are not that means.

I still have this position on classes. But I no longer buy that
pessimistic conclusion about WeakMaps. Consider how WeakMaps would be
used by the expansion of classes-with-private. Just 'cause it's on the
top of my head, below I use the old representation of one WeakMap per
class providing access to a record of all the private state. For the
same reason, I'll use the encapsulation of the Purse example without
any of the numeric checks.

class Purse {
 constructor(private balance) {
 getBalance() { return balance; }
 makePurse() { return Purse(0); }
 deposit(amount, srcPurse) {
 private(srcPurse).balance -= amount;
 balance += amount;
 }
}

expansion
I don't understand the need to expand. This is the class syntax. It 
creates a constructor. Instances of this constructor have some behavior 
and characteristics described by the class body. If the class body 
allows to define something private, implementors will implement that and 
work very hard on performance. I don't think implementors will expand 
before compiling and using the class syntax as some sort of macro 
(implementors are free to tell I'm wrong here).
Assuming I'm right, what it expands to exactly does not matter much, 
whether it's private name or weakmaps or whatever else.


Now you're only talking about privacy in the context of classes in this 
post. I understand this as assuming private symbols would be only use in 
class or class-like contexts (after referred as "this assumption" or 
"the assumption").
If that's your assumption, then I agree that if classes have a "private" 
syntax that is efficiently compiled, private symbols can be dropped.
It has to be noted that if private symbols are dropped, the set of 
private properties is sealed once and for all in the class body. That 
is, it's not possible to add or remove a private property after 
initialization. (However it remains possible to privately attach 
information to an object with a weakmap kept private)


If "private symbols will be only used in class or class-like contexts" 
is your assumption, let's talk about it. Historically, JavaScript 
objects have been used in both in OO contexts and as maps. This 
confusion led to some bugs (involving __proto__ for instance)
As I have suggested in another recent post, most of the time, objects in 
OO contexts are pretty stable: they are created with a given set of 
properties which doesn't change. This stability could even be declared 
statically (that's what the class syntax does actually).
However, for the map use case, it makes sense to add and remove 
properties at runtime.


ES6 adds actual maps, so objects (especially the ones instanciated after 
class-born constructors) could be legitimately considered as reserved 
for OO contexts.
That's a reasoning I agree with since I can't think of cases besides 
classes where private symbols would be used and for which weakmaps 
wouldn't be better.


So I guess I agree with the removal of private symbols given classes 
have a syntax for private properties and no other relevant use case for 
private symbols is found.


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


Re: Security Demands Simplicity (was: Private Slots)

2013-01-17 Thread Herby Vojčík



Mark S. Miller wrote:

I also agree with David that unique symbols are not an encapsulation
mechanism, but rather, merely a mechanism to avoid namespace
collisions.

However, after the "Private Slots" thread, I spent a sleepless night
chewing on getting rid of private symbols. I now think we should.
Going back to my earlier


On Wed, Jan 16, 2013 at 12:37 PM, Mark S. Miller  wrote:

My position on private symbols.

My position on classes is and has always been that classes are worth
introducing into the language *only* if they give us, or can be used
with, an affordable means for true object encapsulation. Assuming
Allen is right about what actual implementors will do (which I find
plausible) then WeakMaps are not that means.


I still have this position on classes. But I no longer buy that
pessimistic conclusion about WeakMaps. Consider how WeakMaps would be
used by the expansion of classes-with-private. Just 'cause it's on the
top of my head, below I use the old representation of one WeakMap per
class providing access to a record of all the private state. For the
same reason, I'll use the encapsulation of the Purse example without
any of the numeric checks.

class Purse { ... an example w/o and w/ external WeakMap

Thus, no matter what the spec says, normatively or not, about expected
storage costs, competitive pressures will drive JS engine implementors
to make this efficient. The way to make this efficient is by the
technique previously discussed -- hang the private state off of the
object, not the weakmap. Use the weakmap only as an unforgeable token
for naming and accessing this state. If we get rid of private symbols,
we should expect this pattern of usage of WeakMap to have the same
cost that private symbols would have had. We can help implementors
achieve that by having this expansion call instead
"WeakMap(USE_KEY_LIFETIME_HINT)" or whatever it is called. Then
implementations would not have to recognize the pattern by other
means.

Complexity is the enemy of security. We already have four
encapsulation mechanisms in ES6 in addition to private symbols:
1) functions encapsulating lexical variables
2) WeakMaps
3) proxies encapsulating handlers and targets
4) modules encapsulating what they don't export.

With enough spec and engineering effort, any of these could be grown
into a means for providing efficient class/object encapsulation. Of
them, I think #2 is most plausible. Even is we find #2 does not work
out, we should think about growing one of the other candidates as an
alternative to private symbols. Security demands simplicity, and
semantic simplicity is more important than implementation simplicity.



This leads me to the question: Are symbols needed at all (even unique 
ones)? They could be implemented using WeakMap (or any other "external 
encapsulator) as well. The only difference is, they would be known and 
reflectanle.


Thus (including my idea in "Private symbols as WeakMap sugar"), if we 
could write


  obj[prop]

and mean

  [[isExternalEncapsulator]](prop) ? prop.get(obj) : legacy obj[prop]

then WeakMaps will simply have @@isExternalEncapsulator return true.

The reflectability is the only other matter to be solved. In case of 
symbols, API like gOPN and Object.keys() was not touched, and other API 
must have been added to include symbols.


So, thinking about it, if there were no symbols at all but there were 
(more generic) encapsulators, one can simply add APIs to return visible 
encapsulators, the same as it return symbols now (the encapsulators need 
to know if they are reflectable or not, of course).


I think there may be less confusion because encapsulators would clearly 
be different beasts than properties; symbols tried to be as similar as 
possible but even then they need different API.



--
 Cheers,
 --MarkM


Herby

P.S.: Now that I think about it, encapsulators need to be weak, so they 
do not keep an instance living; therefore probably only WeakMaps are 
legible to be one.


So alternative proposal is to allow obj[wm] and to allow wm to set 
itself and reflectable/nonreflectable when used in obj[wm]. Thus, wms 
can replace symbols altogether.


P.P.S.: Or not (reacting to "only WeakMaps are legible"). It can be done 
other way: all the external encapsulator are weak by default (in a 
sense, their pointer to instance is not treated as strong). Probably 
just a crazy thought experiment... but in that way, one need no WeakMap, 
just a Map used as external encapsulator to have weak Map ;-)

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


Re: Security Demands Simplicity (was: Private Slots)

2013-01-17 Thread Axel Rauschmayer
Right. That could work in favor of this approach.

On Jan 17, 2013, at 18:35 , Brandon Benvie  wrote:

> Well keep in mind that Symbols of any type already require using a new 
> function, getOwnKeys (or whatever the name is) so they are already 
> essentially "super non-enumerable". They are reflectable if someone really 
> wants to see them, but they are never reflected in Object.keys, 
> Object.getOwnPropertyNames, or for...in enumeration.
> 
> 
> On Thu, Jan 17, 2013 at 12:32 PM, Axel Rauschmayer  wrote:
> Can we separate of concerns?
> 
> 1. I love symbols.
> 
> 2. I also love the idea that you can mark properties as private, as invisible 
> to the outside. Currently I prefix my properties with `_` to do so, but it’s 
> an ugly namespace pollution.
> 
> 3. But, for me and probably most applications, the privacy does not have to 
> be bullet proof. For the rare cases where we need. bullet-proofing, weak maps 
> might be enough.
> 
> 4. Enumerability still seems like something that only exists because for 
> for-in. Unfortunately, it can’t take up role #2, because so many things are 
> already non-enumerable that are clearly public.
> 
> Does that mean that the current ES6 model could be simplified? For example: 
> another property attribute `visible`, making properties invisible. Not sure 
> where the invisibility matters: at an IDE level, when you do an expansion 
> (e.g. type `myobj.`). Or should it also be hidden from all current iteration 
> operations (Object.getOwnPropertyNames() etc.)? In either case, there would 
> still be a way of iterating over all properties, making copying etc. 
> straightforward.
> 
> 
> On Jan 17, 2013, at 18:00 , "Mark S. Miller"  wrote:
> 
>> First, I agree with David that security is important, both for
>> security per se and for modularity in general. ES5 improved the
>> language when it fixed the accidental leaks between the world of
>> objects and scope-chain objects, like thrown functions. ES5/strict
>> improved the language when it made functions really encapsulated,
>> poisoned caller and arguments, and repaired the remaining violations
>> of static scoping. ES6 modules and CommonJS/Node modules were born and
>> remain encapsulated. I have not heard anyone suggesting any of these
>> would be improved by introducing pliers for opening them against their
>> will (except in a debugger, which is a different issue). Tons of code
>> have been written in ES3. We still made the world a better place when
>> we plugged its leaks.
>> 
>> I also agree with David that unique symbols are not an encapsulation
>> mechanism, but rather, merely a mechanism to avoid namespace
>> collisions.
>> 
>> As for Java's reflective breakage of "private",
>> .
>> 
>> 
>> However, after the "Private Slots" thread, I spent a sleepless night
>> chewing on getting rid of private symbols. I now think we should.
>> Going back to my earlier
>> 
>> 
>> On Wed, Jan 16, 2013 at 12:37 PM, Mark S. Miller  wrote:
>>> My position on private symbols.
>>> 
>>> My position on classes is and has always been that classes are worth
>>> introducing into the language *only* if they give us, or can be used
>>> with, an affordable means for true object encapsulation. Assuming
>>> Allen is right about what actual implementors will do (which I find
>>> plausible) then WeakMaps are not that means.
>> 
>> I still have this position on classes. But I no longer buy that
>> pessimistic conclusion about WeakMaps. Consider how WeakMaps would be
>> used by the expansion of classes-with-private. Just 'cause it's on the
>> top of my head, below I use the old representation of one WeakMap per
>> class providing access to a record of all the private state. For the
>> same reason, I'll use the encapsulation of the Purse example without
>> any of the numeric checks.
>> 
>> class Purse {
>>constructor(private balance) {
>>getBalance() { return balance; }
>>makePurse() { return Purse(0); }
>>deposit(amount, srcPurse) {
>>private(srcPurse).balance -= amount;
>>balance += amount;
>>}
>> }
>> 
>> expansion
>> 
>> let Purse = (function() {
>>let amp = WeakMap();
>>function Purse(balance) {
>>amp.set(this, Object.seal({
>>get balance() { return balance; },
>>set balance(newBalance) { balance = newBalance; }
>>}));
>>}
>>Purse.prototype = {
>>getBalance: function() { return balance; },
>>makePurse: function() { return Purse(0); },
>>deposit: function(amount, srcPurse) {
>>amp.get(srcPurse).balance -= amount;
>>}
>>}
>>return Purse;
>> })();
>> 
>> 
>> Ignore the issues about whether we should use one WeakMap per class
>> and a private record as above, or a WeakMap per private field name
>> declaration.
>> 
>> Ignore the use of accessors so that private field names track
>> variables. If we had 

Re: Security Demands Simplicity (was: Private Slots)

2013-01-17 Thread Brandon Benvie
Well keep in mind that Symbols of any type already require using a new
function, getOwnKeys (or whatever the name is) so they are already
essentially "super non-enumerable". They are reflectable if someone really
wants to see them, but they are never reflected in Object.keys,
Object.getOwnPropertyNames, or for...in enumeration.


On Thu, Jan 17, 2013 at 12:32 PM, Axel Rauschmayer  wrote:

> Can we separate of concerns?
>
> 1. I love symbols.
>
> 2. I also love the idea that you can mark properties as private, as
> invisible to the outside. Currently I prefix my properties with `_` to do
> so, but it’s an ugly namespace pollution.
>
> 3. But, for me and probably most applications, the privacy does not have
> to be bullet proof. For the rare cases where we need. bullet-proofing, weak
> maps might be enough.
>
> 4. Enumerability still seems like something that only exists because for
> for-in. Unfortunately, it can’t take up role #2, because so many things are
> already non-enumerable that are clearly public.
>
> Does that mean that the current ES6 model could be simplified? For
> example: another property attribute `visible`, making properties invisible.
> Not sure where the invisibility matters: at an IDE level, when you do an
> expansion (e.g. type `myobj.`). Or should it also be hidden from all
> current iteration operations (Object.getOwnPropertyNames() etc.)? In either
> case, there would still be a way of iterating over all properties, making
> copying etc. straightforward.
>
>
> On Jan 17, 2013, at 18:00 , "Mark S. Miller"  wrote:
>
> First, I agree with David that security is important, both for
> security per se and for modularity in general. ES5 improved the
> language when it fixed the accidental leaks between the world of
> objects and scope-chain objects, like thrown functions. ES5/strict
> improved the language when it made functions really encapsulated,
> poisoned caller and arguments, and repaired the remaining violations
> of static scoping. ES6 modules and CommonJS/Node modules were born and
> remain encapsulated. I have not heard anyone suggesting any of these
> would be improved by introducing pliers for opening them against their
> will (except in a debugger, which is a different issue). Tons of code
> have been written in ES3. We still made the world a better place when
> we plugged its leaks.
>
> I also agree with David that unique symbols are not an encapsulation
> mechanism, but rather, merely a mechanism to avoid namespace
> collisions.
>
> As for Java's reflective breakage of "private",
> <
> http://www.nbcnews.com/technology/technolog/us-warns-java-software-security-concerns-escalate-1B7938755
> >.
>
>
> However, after the "Private Slots" thread, I spent a sleepless night
> chewing on getting rid of private symbols. I now think we should.
> Going back to my earlier
>
>
> On Wed, Jan 16, 2013 at 12:37 PM, Mark S. Miller 
> wrote:
>
> My position on private symbols.
>
> My position on classes is and has always been that classes are worth
> introducing into the language *only* if they give us, or can be used
> with, an affordable means for true object encapsulation. Assuming
> Allen is right about what actual implementors will do (which I find
> plausible) then WeakMaps are not that means.
>
>
> I still have this position on classes. But I no longer buy that
> pessimistic conclusion about WeakMaps. Consider how WeakMaps would be
> used by the expansion of classes-with-private. Just 'cause it's on the
> top of my head, below I use the old representation of one WeakMap per
> class providing access to a record of all the private state. For the
> same reason, I'll use the encapsulation of the Purse example without
> any of the numeric checks.
>
> class Purse {
>constructor(private balance) {
>getBalance() { return balance; }
>makePurse() { return Purse(0); }
>deposit(amount, srcPurse) {
>private(srcPurse).balance -= amount;
>balance += amount;
>}
> }
>
> expansion
>
> let Purse = (function() {
>let amp = WeakMap();
>function Purse(balance) {
>amp.set(this, Object.seal({
>get balance() { return balance; },
>set balance(newBalance) { balance = newBalance; }
>}));
>}
>Purse.prototype = {
>getBalance: function() { return balance; },
>makePurse: function() { return Purse(0); },
>deposit: function(amount, srcPurse) {
>amp.get(srcPurse).balance -= amount;
>}
>}
>return Purse;
> })();
>
>
> Ignore the issues about whether we should use one WeakMap per class
> and a private record as above, or a WeakMap per private field name
> declaration.
>
> Ignore the use of accessors so that private field names track
> variables. If we had instead stored the state in the private field and
> compiled getBalance to use the field, that doesn't affect the
> important issue.
>
>
>
> **
> Notice that the lifetime of amp cannot be shorter than the lifeti

Re: Security Demands Simplicity (was: Private Slots)

2013-01-17 Thread Axel Rauschmayer
Can we separate of concerns?

1. I love symbols.

2. I also love the idea that you can mark properties as private, as invisible 
to the outside. Currently I prefix my properties with `_` to do so, but it’s an 
ugly namespace pollution.

3. But, for me and probably most applications, the privacy does not have to be 
bullet proof. For the rare cases where we need. bullet-proofing, weak maps 
might be enough.

4. Enumerability still seems like something that only exists because for 
for-in. Unfortunately, it can’t take up role #2, because so many things are 
already non-enumerable that are clearly public.

Does that mean that the current ES6 model could be simplified? For example: 
another property attribute `visible`, making properties invisible. Not sure 
where the invisibility matters: at an IDE level, when you do an expansion (e.g. 
type `myobj.`). Or should it also be hidden from all current iteration 
operations (Object.getOwnPropertyNames() etc.)? In either case, there would 
still be a way of iterating over all properties, making copying etc. 
straightforward.


On Jan 17, 2013, at 18:00 , "Mark S. Miller"  wrote:

> First, I agree with David that security is important, both for
> security per se and for modularity in general. ES5 improved the
> language when it fixed the accidental leaks between the world of
> objects and scope-chain objects, like thrown functions. ES5/strict
> improved the language when it made functions really encapsulated,
> poisoned caller and arguments, and repaired the remaining violations
> of static scoping. ES6 modules and CommonJS/Node modules were born and
> remain encapsulated. I have not heard anyone suggesting any of these
> would be improved by introducing pliers for opening them against their
> will (except in a debugger, which is a different issue). Tons of code
> have been written in ES3. We still made the world a better place when
> we plugged its leaks.
> 
> I also agree with David that unique symbols are not an encapsulation
> mechanism, but rather, merely a mechanism to avoid namespace
> collisions.
> 
> As for Java's reflective breakage of "private",
> .
> 
> 
> However, after the "Private Slots" thread, I spent a sleepless night
> chewing on getting rid of private symbols. I now think we should.
> Going back to my earlier
> 
> 
> On Wed, Jan 16, 2013 at 12:37 PM, Mark S. Miller  wrote:
>> My position on private symbols.
>> 
>> My position on classes is and has always been that classes are worth
>> introducing into the language *only* if they give us, or can be used
>> with, an affordable means for true object encapsulation. Assuming
>> Allen is right about what actual implementors will do (which I find
>> plausible) then WeakMaps are not that means.
> 
> I still have this position on classes. But I no longer buy that
> pessimistic conclusion about WeakMaps. Consider how WeakMaps would be
> used by the expansion of classes-with-private. Just 'cause it's on the
> top of my head, below I use the old representation of one WeakMap per
> class providing access to a record of all the private state. For the
> same reason, I'll use the encapsulation of the Purse example without
> any of the numeric checks.
> 
> class Purse {
>constructor(private balance) {
>getBalance() { return balance; }
>makePurse() { return Purse(0); }
>deposit(amount, srcPurse) {
>private(srcPurse).balance -= amount;
>balance += amount;
>}
> }
> 
> expansion
> 
> let Purse = (function() {
>let amp = WeakMap();
>function Purse(balance) {
>amp.set(this, Object.seal({
>get balance() { return balance; },
>set balance(newBalance) { balance = newBalance; }
>}));
>}
>Purse.prototype = {
>getBalance: function() { return balance; },
>makePurse: function() { return Purse(0); },
>deposit: function(amount, srcPurse) {
>amp.get(srcPurse).balance -= amount;
>}
>}
>return Purse;
> })();
> 
> 
> Ignore the issues about whether we should use one WeakMap per class
> and a private record as above, or a WeakMap per private field name
> declaration.
> 
> Ignore the use of accessors so that private field names track
> variables. If we had instead stored the state in the private field and
> compiled getBalance to use the field, that doesn't affect the
> important issue.
> 
> 
> 
> **
> Notice that the lifetime of amp cannot be shorter than the lifetimes
> of the Point instances, since the instances retain amp, and these
> instances are the only objects ever stored as keys in amp.
> **
> 
> 
> 
> For this usage common pattern, the lifetime of the keys of amp cannot
> outlive the lifetime of amp.
> 
> Thus, no matter what the spec says, normatively or not, about expected
> storage costs, competitive pressures will drive JS engine implemen

Re: Security Demands Simplicity (was: Private Slots)

2013-01-17 Thread Mark S. Miller
(As usual, trying to write code in a hurry actually cost more time :(.
Sorry to have spent every else's time as well :(. )

class Purse {
constructor(private balance) {}
getBalance() { return balance; }
makePurse() { return new Purse(0); }
deposit(amount, srcPurse) {
private(srcPurse).balance -= amount;
balance += amount;
}
}

expansion

let Purse = (function() {
let amp = WeakMap();
function Purse(balance) {
amp.set(this, Object.seal({ balance: balance }));
}
Purse.prototype = {
getBalance: function() { return amp.get(this).balance; },
makePurse: function() { return new Purse(0); },
deposit: function(amount, srcPurse) {
amp.get(srcPurse).balance -= amount;
amp.get(this).balance += amount;
}
}
return Purse;
})();


When I said previously

"Ignore the use of accessors so that private field names track
variables. If we had instead stored the state in the private field and
compiled getBalance to use the field, that doesn't affect the
important issue."

it turns out only the second representation works, as above.

In any case, the "ignore" statement remains. This is all besides the
point I'm really trying to make. I hope my code is now corrected
enough for the real point to be clear. The Ephemeron gc technique
contributes nothing to the ability to reclaim space for such code
because of the relative lifetimes of the map and its keys.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-17 Thread Mark S. Miller
Still not right. I screwed up the scoping of the "balance" variable.
Another correction coming soon.

On Thu, Jan 17, 2013 at 9:17 AM, Mark S. Miller  wrote:
> On Thu, Jan 17, 2013 at 9:13 AM, Andreas Rossberg  wrote:
>> Hm, I'm afraid I don't fully understand that example. There seems to
>> be a missing closing brace for the constructor, and I don't know what
>> the free occurrences of 'balance' are referring to. Also, the second
>> line of the deposit function seems to be missing in the expansion.
>
> You're right. I also forgot a "new". Corrected I think:
>
>
> class Purse {
> constructor(private balance) {}
> getBalance() { return balance; }
> makePurse() { return new Purse(0); }
> deposit(amount, srcPurse) {
> private(srcPurse).balance -= amount;
> balance += amount;
> }
> }
>
> expansion
>
> let Purse = (function() {
> let amp = WeakMap();
> function Purse(balance) {
> amp.set(this, Object.seal({
> get balance() { return balance; },
> set balance(newBalance) { balance = newBalance; }
> }));
> }
> Purse.prototype = {
> getBalance: function() { return balance; },
> makePurse: function() { return new Purse(0); },
> deposit: function(amount, srcPurse) {
> amp.get(srcPurse).balance -= amount;
> balance += amount;
> }
> }
> return Purse;
> })();
>
>
> Please let me know if anything else remains mysterious or looks wrong.
>
> --
> Cheers,
> --MarkM



-- 
Cheers,
--MarkM
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-17 Thread Mark S. Miller
On Thu, Jan 17, 2013 at 9:13 AM, Andreas Rossberg  wrote:
> Hm, I'm afraid I don't fully understand that example. There seems to
> be a missing closing brace for the constructor, and I don't know what
> the free occurrences of 'balance' are referring to. Also, the second
> line of the deposit function seems to be missing in the expansion.

You're right. I also forgot a "new". Corrected I think:


class Purse {
constructor(private balance) {}
getBalance() { return balance; }
makePurse() { return new Purse(0); }
deposit(amount, srcPurse) {
private(srcPurse).balance -= amount;
balance += amount;
}
}

expansion

let Purse = (function() {
let amp = WeakMap();
function Purse(balance) {
amp.set(this, Object.seal({
get balance() { return balance; },
set balance(newBalance) { balance = newBalance; }
}));
}
Purse.prototype = {
getBalance: function() { return balance; },
makePurse: function() { return new Purse(0); },
deposit: function(amount, srcPurse) {
amp.get(srcPurse).balance -= amount;
balance += amount;
}
}
return Purse;
})();


Please let me know if anything else remains mysterious or looks wrong.

--
Cheers,
--MarkM
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Security Demands Simplicity (was: Private Slots)

2013-01-17 Thread Andreas Rossberg
On 17 January 2013 18:00, Mark S. Miller  wrote:
> I still have this position on classes. But I no longer buy that
> pessimistic conclusion about WeakMaps. Consider how WeakMaps would be
> used by the expansion of classes-with-private. Just 'cause it's on the
> top of my head, below I use the old representation of one WeakMap per
> class providing access to a record of all the private state. For the
> same reason, I'll use the encapsulation of the Purse example without
> any of the numeric checks.
>
> class Purse {
> constructor(private balance) {
> getBalance() { return balance; }
> makePurse() { return Purse(0); }
> deposit(amount, srcPurse) {
> private(srcPurse).balance -= amount;
> balance += amount;
> }
> }

Hm, I'm afraid I don't fully understand that example. There seems to
be a missing closing brace for the constructor, and I don't know what
the free occurrences of 'balance' are referring to. Also, the second
line of the deposit function seems to be missing in the expansion.

>
> expansion
>
> let Purse = (function() {
> let amp = WeakMap();
> function Purse(balance) {
> amp.set(this, Object.seal({
> get balance() { return balance; },
> set balance(newBalance) { balance = newBalance; }
> }));
> }
> Purse.prototype = {
> getBalance: function() { return balance; },
> makePurse: function() { return Purse(0); },
> deposit: function(amount, srcPurse) {
> amp.get(srcPurse).balance -= amount;
> }
> }
> return Purse;
> })();
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss