Symbols, Protocols, Frames, and Versioning

Allen Wirfs-Brock allen at wirfs-brock.com
Fri Oct 5 09:19:10 PDT 2012


On Oct 5, 2012, at 7:11 AM, Sam Tobin-Hochstadt wrote:

> On Fri, Oct 5, 2012 at 8:45 AM, Andreas Rossberg <rossberg at google.com> wrote:
>> Indeed, which is why I'm not sure I understand what this idea is
>> trying to achieve. Is it more than just an ad hoc way to introduce a
>> second namespace?
> 
> I think what's going on as follows:
> 
> - Symbols, even when not used for encapsulated abstractions, are
> great for avoiding the possibility of collision in the global string
> namespace
> - So, we (tc39) decided to use them for to replace the property name
> currently called "iterator" in Spidermonkey.
> - Currently, "iterator" works across same-origin frames, but a naive
> use of Symbol for this wouldn't work

(note @@foo is how, within the specification, I refer to the value of a well known symbol)

This isn't just about @@iterator.  @@iterator is just one example of a place where an object property is use to complete or extend the semantics of a language construct or built-in library feature. @@iterator is a hook by which the for-of statement obtains an iterator object.  @@toStringTag is a hook that is used to extend the built-in Object.prototype.toString method.  The Object Model Reformation strawman proposes adding @@elementGet, @@elementSet, and @@elementDelete hooks.  There have been informal proposals for a @@construct hook for the new operator.  All of these usages require universal identify  across all Realms (frames) that are able to interchange executable functions.

Properties with these keys all implement interfaces that face towards the language implementation. The are "meta" in at least one sense of that term.  They also all exist on objects that expose other interfaces that are intended for general use.  While it isn't absolutely necessary, it seems desirable to separate the keys of these meta interfaces into a distinct namespace.  This prevents accidental punning uses of these meta hooks.  It also permits future extension of the set of meta interface properties without conflicting with property name choices in pre-existing ES code.

Use of Symbols rather than string keys for these meta properties means that code that wishes to define (or reference) such properties need some way to first obtain access to the corresponding symbol value.  That might be done via:

A built-in module:

import @iterator from "@itr";
or
import @iterator from "@System";

A built-in property:

symbol @toStringTag = Object.prototype.toString.tagSymbol;

or some sort of well known registry that  provides access to these symbol values via some sort of published name associations:

symbol @iterator = MetaSymbolRegistry.lookup("iterator");

or a user extensible cross realm symbol registry:

symbol @iterator = Symbol.for("iterator");

We have to make a design decision regarding which of these approaches to take, but some such approach is required if we intend to use symbols for meta property keys and and at-names to access them.  Whichever form we choose, they all need to produce common symbol values that span all connected realms.


> - Therefore, we have a few options:
>   1 Give up on Symbols for "iterator"
>   2 Make the Symbol replacement for "iterator" magically work across
> all same-origin frames
>   3 Make iteration not work across frames
>   4 Break the web and fix cross-frames to work more sensibly
> - Since the latter two of those are not actual options, (2) seemed
> like the best choice.
> - But then we, the language, are doing something that programmers
> can't do, so we searched for something else
> - This led to `Symbol.for`, which is not actually allowing
> programmers to do (2), but resembles it somewhat

yes, but of course, ,it's not just @@iterator.

> 
> I think we should rethink this whole direction. The bizarreness of
> cross-frame interaction is real, and we have to deal with it.  That
> means abstractions based on libraries that provide values with
> identity won't work cross-frame.  I don't think `Symbol.for` makes
> solving any problems that we currently have easier.  Symbols are great
> when they're based on sharing values in the heap, and otherwise, we're
> stuck with strings.  We can make @iterator a magic Symbol, or we can
> stick with a string, and I don't have a good sense of what the right
> choice is there, but I think that's separable from `Symbol.for`.
> 

To me, this is clearly a module loader level issue as it concerns the creation and initial sharing between related realms (module loader contexts).

Consider all of the above alternative techniques for accessing a well known meta symbol. They all involve either access to a a "build-iin" module that would need to be resolved by a module loader or start with a reference to a global binding that would have been initially established by a module loader. In either case, the creator of the module loader for such a realm could initialize it in a way that passes the appropriate symbol values.  Anybody creating their own new symbol "namespace" that they wanted to share between realms could set up there own registry mechanism and coordinate its sharing among the realms it it creates.

> Note also that `Symbol.for` has some really weird behavior. For
> example, what does this evaluate to?
> 
>    Symbol.for("x") instanceof Symbol

I haven't had time to devote to the typeof Symbol thread, so I don't want to naively jump into the middle of that discussion.

However, the above is one of the reasons that my starting point is that symbol values should be primitive values rather than object instances.  Or alternatively, why Symbol should not be a constructor and instead a symbol/private declaration should be the only way to instantiate a new symbol.

However, even if they are objects and Symbol is a constructor, instanceof Symbol can be made to work across realms simply by specifying the [[HasInstance]] internal method of Symbol appropriately.

> 
> That depends if someone has previously evaluated `Symbol.for("x")` in
> a different frame.

No, the intended semantics of Symbol.for is that it maintains a single cross realm (frame) registry of symbol values.

Allen
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20121005/34f4d6e5/attachment.html>


More information about the es-discuss mailing list