Symbols, Protocols, Frames, and Versioning

Brendan Eich brendan at mozilla.org
Wed Oct 3 14:09:00 PDT 2012


Domenic Denicola wrote:
> Would it suffice to allow cross-frame sharing of symbols via postMessage and its structured clone algorithm? They're immutable, right?

They are immutable but you'd still have to pass your @iterator to 
another same-origin frame, and then have to use it carefully when 
iterating objects from the first frame. This is unusable.

Making @iterator a singleton (to the limits of observability: 
same-origin, CORS, out-of-process-via-DOM window.open in IE9+ 
notwithstanding!) can be done. That wins, no need to pass and use the 
other frame's @iterator symbol.

But how to let users create such singletons?

/be

>
> On Oct 3, 2012, at 15:01, "Brendan Eich"<brendan at mozilla.org>  wrote:
>
>> Thanks for pointing this out. Python's dunder-prefixing or anything like it in JS has that advantage: you can spell the magic property name with a string that works in any frame or global object. Of course strings can collide.
>>
>> Symbols are useful in spite of this, but it is telling that we want @iterator to be a singleton across all potentially connected frames.
>>
>> So should there be a way in the language to create singleton symbols? If so, how?
>>
>> /be
>>
>> Kevin Smith wrote:
>>> One of the main use cases for symbols is for defining object "protocols" that don't suffer from property name conflicts.  The recently discussed `iterator` and `toStringTag` method names fall into this category.  The idea is that we can implement the protocol by defining methods using symbols, and thus avoid namespacing considerations.
>>>
>>> Designing and maintaining a global namespace is, well, no fun.
>>>
>>> But consider the multiple-global case in which we have scripts running in more than one frame.  It seems like protocols should be transferrable across frames.  For built-in protocols like `iterator`, this has to work:
>>>
>>>     function f(iterable) {
>>>       for (x of iterable) {
>>>         // This must work regardless of which frame `iterable` comes from
>>>       }
>>>     }
>>>
>>> But what about user-defined protocols?  Let's say we have a "Persistable" protocol:
>>>
>>>     export var persistName = new Symbol; // unique, not "private"
>>>
>>> And a function which makes use of this protocol:
>>>
>>>     import persistName from "Persistable.js";
>>>
>>>     function usePersistable(obj) {
>>>
>>>       if (obj[persistName])
>>>         obj[persistName]();
>>>     }
>>>
>>> It seems like `usePersistable` should be able to work as expected even if `obj` comes from a different frame (in which "Persistable.js" was separately loaded).
>>>
>>> Another expression of the same problem occurs with versioning.
>>>
>>> Suppose that in a fairly complex module dependency graph, "Persistable-0.1.js" and "Persistable-0.2.js" are simultaneously loaded. ("Persistable" is on github and therefore in perpetual version-zero purgatory.)  It seems reasonable to expect that objects implementing the protocol defined by "Persistable-0.2.js" should be able to work with functions consuming the "Persistable-0.1.js" protocol.  But that is not possible with unique symbols.
>>>
>>> In summary, I don't think that we can really avoid global namespacing issues using system-generated unique symbols as we currently conceive of them.  Built-in protocols like `iterator` are a special "cheating" case, but we need to have an equally consistent story for user-defined protocols.
>>>
>>> Kevin
>>>
>>>
>>> _______________________________________________
>>> es-discuss mailing list
>>> es-discuss at mozilla.org
>>> https://mail.mozilla.org/listinfo/es-discuss
>> _______________________________________________
>> es-discuss mailing list
>> es-discuss at mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>


More information about the es-discuss mailing list