On Oct 1, 2012, at 3:48 PM, Brendan Eich wrote:

> Allen Wirfs-Brock wrote:
>>> 
>>> 
>> 
>> Let me try explaining this again,
> 
> No need to rehash.
> 
> Responding to my point about other legacy "tag tests" that are not twiddled 
> with "~" and so are possibly "invalidated" would be helpful. *Why* are the 
> core language names sacrosanct when tag-testing of other class names is also 
> potentially just as important, e.g., for SES?


My main concern isn't SES-like things.  It is random general use of 
Obj.proto.toString to identify instances of built-ins such as Array and 
Function.

I think we have to support reliable Obj.proto.toString-based tag-test for 
"Arguments", "Array", "Boolean", "Date", "Error", "Function", "JSON", "Math", 
"Number", "RegExp", and "String" because those specific values are explicitly 
defined in the ES5.1 specification and are universally supported by 
implementations.  Assigning one of those tags (via @@toStringTag or any other 
mechanism) may break existing code. 

The only other legacy tag tests presumably are of DOM objects (or other 
non-standard built-ins).  I don't thing we have an obligation to preserve 
legacy code with such dependencies that isn't already universally 
interoperable.  I would be more concerned about the DOM objects if there had 
been a history of consistency of tag values among implementations (but we may 
be racing the WebIDL implementation clock in this regard).  

Also as we move into a much larger space of classes and that includes the 
possibility of self-hosting libraries such as the DOM it is rapidly becoming 
impractical to guarantee the unique mapping to such toString tags to specific 
implementations of an abstraction.

So, my position is that we only guarantee the above toString tag tests that are 
carry overs from ES <= 5.1and that we loudly state Obj.proto.toString can not 
be used as a reliable nominal type tag for any other objects.  We essentially 
(except for the  11 above cases) let Obj.proto.toString revert to its rightful 
place as a debugging aid.

> 
>> The little quicks like the "~" prefix and the exception eating are simply 
>> what is necessary
> 
> Not so fast there, Tex!
> 
> First, *something* is necessary for preserving certain names from being 
> spoofed and invalidating a tag-test, but we should agree on the names and the 
> reason for spoof-proofing exactly and only that set of names.

Of course, there are other ways of preventing spoofing.  The key point is we 
need to avoid spoofing that interferes with legacy test of the 11 ES5  tags. 

> 
> Second, eating exceptions does *not* follow from "what is necessary" even if 
> I agree with your set of names! Eating exceptions is bad on principle. Why do 
> you do it here? A host object might throw on attempt to get a novel property 
> name such as @@toStringTag but is that an actual concern?

Yes, eating exception is  a separable issue. But I have thought of it as a 
compatibility issue.  Obj.proto.toString never throws in ES<=5.1.  Adding 
conditions where it does throw seems like a potentially breaking change.  For 
example, an self-host object inspector implementation many not currently be 
wrapping calls to Obj.proto.toString with an exception handler because it 
thinks that call never throws.

Once we get beyond using Obj.proto.toString as a nominal type tester, its 
primary use is going to be as a diagnostic/debugging aid.  From that 
perspective having the tag access throw what is likely to be an uncaught 
exception seems undesirable.  Better to just indicate in the "debug" text that 
an some unexpected occurred.

> 
> Also, I'm assuming the "???" strings are just place-holders. True?

Sure, it could be any thing, include a description of the exception that 
occurred. 
> 
>>  to formalize this extensibility model while still preserving the behavior 
>> of existing code that depends upon object.prototype.toString as a reliable 
>> mechanism to test for instances of the ES<=5.1 built-ins.
> 
> Adding new internal method calls with novel ids might add new exception 
> throws. That's part of the package deal.

Yes, in general I agree.  But given the primarily debugging use of 
@@toStringTag, an exception seems undesirable.  If we were talking about 
something like @@interator I would agree that eating exceptions would be highly 
undesirable.

> 
> Implementors control their host objects in general and can tame any that 
> might throw on @@toStringTag [[Get]]. Suppose an implementation has a bug 
> where such a throw happens, for any reason (could be the novel symbol 
> property-name, or could be some other reason). Suppressing prevents anyone 
> (implementor, developer, us) from knowing what is going on.

But we aren't just talking about platform implementors and host objects.  This 
is now an extension point that anyone defining a set of classes might (probably 
should) use. 
> 
> I'm laboring over this because in JS1 I suppressed exceptions trying toString 
> and valueOf and that bit back. [[DefaultValue]] uses ReturnIfAbrupt which 
> propagates the abrupt completion rather than dropping it on the floor.

[[DefaultValue]] must ReturnIfAbrupt because that is what current 
implementations do.  I would guess that where you go bit ij [[DefaultValue]] 
eating exception from toString/valueOf was in situations where they were 
actually being over-ridden to provide useful conversion behavior that was 
buggy.  But in this case, we have already bottomed out in 
Obj.prototype.toString which has been long known to always return a string and 
never an exception.  My trickery was just trying to maintain that postcondition.

Eating tag access exception within Obj.proto.toString  probably isn't essential 
but it still feel slightly more desirable to me than having in throw in these 
corner cases.

Allen






_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to