Right. That could work in favor of this approach. On Jan 17, 2013, at 18:35 , Brandon Benvie <[email protected]> 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 <[email protected]> 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" <[email protected]> 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 <[email protected]> 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 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. >> >> >> >> -- >> Cheers, >> --MarkM >> _______________________________________________ >> es-discuss mailing list >> [email protected] >> https://mail.mozilla.org/listinfo/es-discuss >> > > -- > Dr. Axel Rauschmayer > [email protected] > > home: rauschma.de > twitter: twitter.com/rauschma > blog: 2ality.com > > -- Dr. Axel Rauschmayer [email protected] home: rauschma.de twitter: twitter.com/rauschma blog: 2ality.com
_______________________________________________ es-discuss mailing list [email protected] https://mail.mozilla.org/listinfo/es-discuss

