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<erig...@google.com> 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