There is a paragraph in the original e-mail that I forgot. Adding it below:
Le 16/12/2011 12:19, David Bruant a écrit : > Hi, > > I couldn't post on es-discuss yesterday, so I rewrote my message and > posted it on github [1]. Here is the markdown source: > > # PART 1: The same feature? > When looked abstractly, both private name and weak maps propose an > equivalent feature: a mapping between 2 unforgeable references and a value. > Both allow to share a secret with someone assuming the knowledge of 2 > unforgeable entities. > Both have the interesting property of symmetric non-discoverability: > > * Given an object, you can't list all private names > * Given a private name, you can't list all objects which have this name > as a property > * Given a weak map, you can't list all objects used as keys > * Given an object, you can't list all weak maps using this object as key > > This can be used in WeakMaps to optimize garbage collection. As it turns > out, the same thing stands for private names: If nothing holds a > reference to a private name, all related slots in objects can be > garbage-collected as well. > > There are a couple of differences: > > * A private property can be made non-configurable & non-writable > * A private name can refer to an accessor property > > I claim that these can be reimplemented by overriding the WeakMap API. > > I'm open to discussion on whether there are cases that can be > implemented with one API and not the other. For the rest of this > message, I'll assume that it's the same feature with 2 different syntax. > > > # PART 2: A more generic syntax > Unfortunately, private names and WeakMaps (and maps and sets...) both > define a special new sort of object to work. What about an API that > would allow to associate any 2 objects and bind a "secret" value to the > association? > > `````JavaScript > // In one part of the code > var o1 = {}, > o2 = {}; > var a = Assoc(o1, o2); > a.set(37); > > // ... > // In another component which has a reference to both o1 and o2 > var myA = Assoc(o1, o2); > myA.get(); // 37 > ````` > > In order to unseal a secret associated with 2 objects, you need a > reference to both, that's it. Exactly like with WeakMaps, exactly like > with private names. > > > ## Part 2.1: where I pretend I can reimplement WeakMaps with the Assoc API > > `````JavaScript > WeakMap = function(){ > var weakMapIdentity = {}; > var presence = {}; > > return { > get: function(o){ > return Assoc(weakMapIdentity, o).get(); > }, > set: function(o, val){ > Assoc(presence, o).set(true); > return Assoc(weakMapIdentity, o).set(val); > }, > has: function(o){ > return !!Assoc(presence, o).get(); > }, > delete = function(o){ > Assoc(presence, o).set(undefined); > } > } > } > ````` > > Interestingly, 2 identities are required to emulate weakmaps. One for > the values (weakMapIdentity) and one to consider presence of keys. In my > opinion, the WeakMap API should be separated into 2 APIs. One with > get/set and the other with add/remove/has which would find the natural > name of WeakSet. > > > ## Part 2.2: where I go further and get a bit crazy > > Some properties: > > * Assoc() === Assoc // why waste a reference? :-p > * Assoc(o) !== o > * Assoc(o) === Assoc(o) > * Assoc(Assoc(o)) === Assoc(o) > * Assoc(o, o) === Assoc(o) > * Assoc(o1, o2) === Assoc(o2, o1) > > The Assoc API could be extended with any number of arguments. The > resulting object represents the association of all objects passed as > arguments. > > * Assoc(o1, o2, o3) === Assoc(Assoc(o1, o2), o3) === Assoc(o1, > Assoc(o2, o3)) > * ...and these applies to any number of arguments. > > Long story short, the Assoc function only cares about whether or not you > pass it the right references to unseal the secret. > And you should not care about passing the objects in the "right order". > If I want to keep a secret from you, I'll create an unforgeable > reference; I won't try to "obscure" it by not telling you the order in > which you should pass the objects to Assoc > > Of course, since there is no discoverability of associations, all good > garbage collection optimizations are kept. > > > With association objects, I think we can have a uniform base to play > with objects without having to invent new sorts of objects (WeakMaps, > Sets, Maps, etc.) while keeping the possibility to implement (hopefully > as efficiently) these abstractions. I'm not sure we should give up on private names though. They provide a very efficient syntax for private accessors. They could be considered as syntactic sugar of the Assoc API. Moreover, I think we need a way to create unforgeable tokens which would be clearer than "Object.freeze({})" or "name.create()". This is very verbose to represent the creation of a token. What about some grawlix-y syntax for that? {*} > I've had some comments from Erik Corry on Twitter. > [2] "Can you add a private property to a frozen object?" > => This is not discussed in the proposal [4]. I would guess not. It may > be a difference indeed between WeakMaps and private names, but I think > it'd be possible to enhance the WeakMap API to allow either that a > weakmap stops accepting keys or that an object is banned from all > weakmaps (which are 2 different view of non-extensibility) > I forgot to say that the Assoc API was a first shot and of course some > additional primitives may be handy. This is what I'd like to explore. > > > [3] "For private names you can make a polyfill based on ES5 > non-enumerability and random strings. Can u do that with Assoc?" > => The polyfill would be only partial, because properties would appear > anyway with Object.getOwnPropertyNames which defeats the purpose of > private names. > Moreover, there would always be a risk of collision (which can't happen > with private names thanks to the unforgeability property). > Private names have been added because they add something that lack to > the language. The Assoc API would do the same and any polyfill could > only be partial (same goes for WeakMaps) > > David > > [1] https://gist.github.com/1483744 > [2] https://twitter.com/#!/erikcorry/status/147589242246275073 > [3] https://twitter.com/#!/erikcorry/status/147588955611729920 > [4] http://wiki.ecmascript.org/doku.php?id=harmony:private_name_objects _______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss