Jordan Harband (2015-01-20T20:13:11.000Z)
Between the two issues I proposed, I definitely think that "something
pretending to be a builtin" is far less hazardous then "altering builtins
to appear to be something else". If removing the prefixing entirely is what
it takes to make *all* (not just ES5) builtin @@toStringTag values
non-configurable, I'd be happy with that.

That said, new code interacting with old code is indeed the hazard, since
the old code won't know anything about ES6.

> But in these cases developers have plenty of opportunities to test the
interaction. And they quite probably are introducing the "Array" return
value specifically to go down a specific code path in the old code. (For
example, if they have created an array-like proxy that behaves like an
Array in all other ways.) The current spec forces them to instead override
Object.prototype.toString itself if they want to go down that path.
If it's a proxy to an actual array, wouldn't @@toStringTag be proxied too?
If it's not a proxy to an actual array, why is the fact that it's a proxy
relevant - it seems like your question is the same if you say "array-like
object" also? Just to be sure I'm understanding. The real issue, as you've
pointed out, is that there's no easy way to answer the question "does this
value behave like an array" short of either ducktyping, or treating it like
one, and seeing if it breaks. Let's fix that problem instead of allowing
people to misuse @@toStringTag as an attempt to fake an answer to that
question.

On Tue, Jan 20, 2015 at 11:45 AM, Domenic Denicola <d at domenic.me> wrote:

> From: es-discuss [mailto:es-discuss-bounces at mozilla.org] On Behalf Of
> Jordan Harband
>
> > It appears that TC39 considers it important to not break existing JS
> code with spec changes. Thus, `Object.prototype.toString.call(foo)`, for
> any ES5 value "foo", must always and forever return the same value that it
> returned in ES5 - otherwise, existing code may follow different code paths
> in ES5 versus ES6, which is a hazard. This leads me to the belief that
> @@toStringTag values on ES5 builtins should never be changeable.
>
> I don't think this reasoning, or in fact the reasoning that leads to the
> current tilde-prefixing, is sound.
>
> First we must realize that if we were to remove the tilde-prefixing, no
> deployed code would ever break. Only new code (which returns e.g. "Array"
> from the @@toStringTag) *interacting with old code* (which tests for
> "[object Array]") would be affected.
>
> But in these cases developers have plenty of opportunities to test the
> interaction. And they quite probably are introducing the "Array" return
> value specifically to go down a specific code path in the old code. (For
> example, if they have created an array-like proxy that behaves like an
> Array in all other ways.) The current spec forces them to instead override
> Object.prototype.toString itself if they want to go down that path.
>
> So I think the tilde-prefixing is certainly not necessary, and in fact is
> counterproductive in all cases I can think of.
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20150120/1e66f2fa/attachment.html>
ljharb at gmail.com (2015-01-20T20:16:52.816Z)
Between the two issues I proposed, I definitely think that "something
pretending to be a builtin" is far less hazardous then "altering builtins
to appear to be something else". If removing the prefixing entirely is what
it takes to make *all* (not just ES5) builtin @@toStringTag values
non-configurable, I'd be happy with that.

That said, new code interacting with old code is indeed the hazard, since
the old code won't know anything about ES6.

> But in these cases developers have plenty of opportunities to test the interaction. And they quite probably are introducing the "Array" return value specifically to go down a specific code path in the old code. (For example, if they have created an array-like proxy that behaves like an Array in all other ways.) The current spec forces them to instead override Object.prototype.toString itself if they want to go down that path.

If it's a proxy to an actual array, wouldn't @@toStringTag be proxied too?
If it's not a proxy to an actual array, why is the fact that it's a proxy
relevant - it seems like your question is the same if you say "array-like
object" also? Just to be sure I'm understanding.

The real issue, as you've pointed out, is that there's no easy way to answer the question "does this value behave like an array" short of either ducktyping, or treating it like one, and seeing if it breaks. Let's fix that problem instead of allowing people to misuse @@toStringTag as an attempt to fake an answer to that question.
ljharb at gmail.com (2015-01-20T20:16:29.741Z)
Between the two issues I proposed, I definitely think that "something
pretending to be a builtin" is far less hazardous then "altering builtins
to appear to be something else". If removing the prefixing entirely is what
it takes to make *all* (not just ES5) builtin @@toStringTag values
non-configurable, I'd be happy with that.

That said, new code interacting with old code is indeed the hazard, since
the old code won't know anything about ES6.

> But in these cases developers have plenty of opportunities to test the interaction. And they quite probably are introducing the "Array" return value specifically to go down a specific code path in the old code. (For example, if they have created an array-like proxy that behaves like an Array in all other ways.) The current spec forces them to instead override Object.prototype.toString itself if they want to go down that path.

If it's a proxy to an actual array, wouldn't @@toStringTag be proxied too?
If it's not a proxy to an actual array, why is the fact that it's a proxy
relevant - it seems like your question is the same if you say "array-like
object" also? Just to be sure I'm understanding. The real issue, as you've
pointed out, is that there's no easy way to answer the question "does this
value behave like an array" short of either ducktyping, or treating it like
one, and seeing if it breaks. Let's fix that problem instead of allowing
people to misuse @@toStringTag as an attempt to fake an answer to that
question.
ljharb at gmail.com (2015-01-20T20:16:21.616Z)
Between the two issues I proposed, I definitely think that "something
pretending to be a builtin" is far less hazardous then "altering builtins
to appear to be something else". If removing the prefixing entirely is what
it takes to make *all* (not just ES5) builtin @@toStringTag values
non-configurable, I'd be happy with that.

That said, new code interacting with old code is indeed the hazard, since
the old code won't know anything about ES6.

> But in these cases developers have plenty of opportunities to test the interaction. And they quite probably are introducing the "Array" return value specifically to go down a specific code path in the old code. (For example, if they have created an array-like proxy that behaves like an Array in all other ways.) The current spec forces them to instead override Object.prototype.toString itself if they want to go down that path.
If it's a proxy to an actual array, wouldn't @@toStringTag be proxied too?
If it's not a proxy to an actual array, why is the fact that it's a proxy
relevant - it seems like your question is the same if you say "array-like
object" also? Just to be sure I'm understanding. The real issue, as you've
pointed out, is that there's no easy way to answer the question "does this
value behave like an array" short of either ducktyping, or treating it like
one, and seeing if it breaks. Let's fix that problem instead of allowing
people to misuse @@toStringTag as an attempt to fake an answer to that
question.