=== again (sorry)

# Mark S. Miller (17 years ago)

According to the ES3.1 spec and the behavior of at least FF3.0.3

[4, -0, 0, NaN, 8].indexOf(0); // yields 1
[4, -0, 0, NaN, 8].indexOf(NaN); // yields -1

This is because indexOf and lastIndexOf are specified in terms of === rather than SameValue. Is there any reason not to consider this a bug that should be fixed? In ES-Harmony, we've agreed that Map lookup will be according to SameValue (i.e. Object.eq or Object.identical).

The indexOf and lastIndexOf methods are new in ES3.1, and are the only methods in the entire spec that depend on ===. So it's not too late to fix this.

# Maciej Stachowiak (17 years ago)

On Oct 31, 2008, at 4:48 PM, Mark S. Miller wrote:

According to the ES3.1 spec and the behavior of at least FF3.0.3

[4, -0, 0, NaN, 8].indexOf(0); // yields 1 [4, -0, 0, NaN, 8].indexOf(NaN); // yields -1

This is because indexOf and lastIndexOf are specified in terms of === rather than SameValue. Is there any reason not to consider this a bug that should be fixed? In ES-Harmony, we've agreed that Map lookup will be according to SameValue (i.e. Object.eq or Object.identical).

The indexOf and lastIndexOf methods are new in ES3.1, and are the only methods in the entire spec that depend on ===. So it's not too late to fix this.

I think on its merits the change you suggest makes sense.

But indexOf and lastIndexOf have been implemented cross-non-IE browser
for some time, so there is some small risk they are being used in non- IE code paths on dual code-path sites and therefore a risk that
content depends on the existing behavior.

It's probably worth doing some research to quantify the risk.

, Maciej

# David-Sarah Hopwood (17 years ago)

Mark S. Miller wrote:

According to the ES3.1 spec and the behavior of at least FF3.0.3

[4, -0, 0, NaN, 8].indexOf(0); // yields 1
[4, -0, 0, NaN, 8].indexOf(NaN); // yields -1

This is because indexOf and lastIndexOf are specified in terms of === rather than SameValue. Is there any reason not to consider this a bug that should be fixed? In ES-Harmony, we've agreed that Map lookup will be according to SameValue (i.e. Object.eq or Object.identical).

The indexOf and lastIndexOf methods are new in ES3.1, and are the only methods in the entire spec that depend on ===.

In that case it should certainly be fixed.

# Erik Arvidsson (17 years ago)

I see a small risk with changing this. Array.prototype.indexOf is
widely emulated in IE and is also used a lot in browser that support it.

This change would cause issues with NaN and -0. However I don't think
that changing these 2 edge cases would lead to too many serious issues.

2008/10/31 David-Sarah Hopwood <david.hopwood at industrial- designers.co.uk>:

# David-Sarah Hopwood (17 years ago)

Erik Arvidsson wrote:

I see a small risk with changing this. Array.prototype.indexOf is widely emulated in IE and is also used a lot in browser that support it.

If it is emulated, then the emulation will replace the ES3.1 version, so there can be no compatibility problem in that case.

Overall this change will probably fix more bugs in existing code than it introduces.

# Mike Cowlishaw (17 years ago)

Re: === again (sorry)

I see a small risk with changing this. Array.prototype.indexOf is widely emulated in IE and is also used a lot in browser that support it.

This change would cause issues with NaN and -0. However I don't think that changing these 2 edge cases would lead to too many serious issues.

Those two cases are not 'edge cases' to mathematicians and the IEEE 754 standards committee. I confess that I am no longer up-to-date on all the details of the particular ECMAScript methods, but -- please -- do not put in place changes that would make it difficult for ECMAScript to interact with languages that do support IEEE 754.

For example, ES3 makes no distinction between quiet NaNs and signaling NaNs. Some future ECMScript will surely need to, in order to accept and return those values with other languages and systems that do support IEEE 754.

Mike

Unless stated otherwise above: IBM United Kingdom Limited - Registered in England and Wales with number 741598. Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU

# Maciej Stachowiak (17 years ago)

On Nov 3, 2008, at 11:34 AM, David-Sarah Hopwood wrote:

Erik Arvidsson wrote:

I see a small risk with changing this. Array.prototype.indexOf is
widely emulated in IE and is also used a lot in browser that support it.

If it is emulated, then the emulation will replace the ES3.1 version, so there can be no compatibility problem in that case.

Overall this change will probably fix more bugs in existing code than it introduces.

Have you done any testing that provides evidence for this claim? I'm
personally unsure one way or the other. Past experience shows that we
can't determine if a "bug fix" will break existing Web sites just from
armchair reasoning.

, Maciej

# David-Sarah Hopwood (17 years ago)

Maciej Stachowiak wrote:

On Nov 3, 2008, at 11:34 AM, David-Sarah Hopwood wrote:

Erik Arvidsson wrote:

I see a small risk with changing this. Array.prototype.indexOf is widely emulated in IE and is also used a lot in browser that support it.

If it is emulated, then the emulation will replace the ES3.1 version, so there can be no compatibility problem in that case.

(This claim is not conditional on testing.)

Overall this change will probably fix more bugs in existing code than it introduces.

Have you done any testing that provides evidence for this claim?

No, but neither has anyone arguing against the change. If I had done testing, I would have made a stronger claim than "probably".

# Maciej Stachowiak (17 years ago)

On Nov 3, 2008, at 6:54 PM, David-Sarah Hopwood wrote:

Maciej Stachowiak wrote:

On Nov 3, 2008, at 11:34 AM, David-Sarah Hopwood wrote:

Erik Arvidsson wrote:

I see a small risk with changing this. Array.prototype.indexOf is
widely emulated in IE and is also used a lot in browser that support it.

If it is emulated, then the emulation will replace the ES3.1
version, so there can be no compatibility problem in that case.

(This claim is not conditional on testing.)

I would expect most emulation is based on first testing for the
presence of the method, thus it won't replace the ES3.1 version.
That's how missing method emulation is often done in JS libraries.
Testing (or code review) could reveal which of us is right.

Overall this change will probably fix more bugs in existing code
than it introduces.

Have you done any testing that provides evidence for this claim?

No, but neither has anyone arguing against the change. If I had done testing, I would have made a stronger claim than "probably".

I am not arguing against the change; I'm not sure anyone is, as such.
But I think any proposed change to existing cross-browser behavior has
to be backed up with some serious evaluation of its compatibility
impact. Even seemingly obvious bugfixes like changing typeof null to
not return "object" have failed to hold up under closer scrutiny.

, Maciej

# Mark S. Miller (17 years ago)

On Mon, Nov 3, 2008 at 7:02 PM, Maciej Stachowiak <mjs at apple.com> wrote:

I am not arguing against the change; I'm not sure anyone is, as such. But I think any proposed change to existing cross-browser behavior has to be backed up with some serious evaluation of its compatibility impact. Even seemingly obvious bugfixes like changing typeof null to not return "object" have failed to hold up under closer scrutiny.

As a teeny bit of testing, I changed indexOf / lastIndexOf in Caja to work as proposed. All our own regression tests run as green as before, so we weren't depending on the difference. Our corpus is so small and so unrepresentative that this provides almost no evidence whatsoever. However, if others on this list with large testing suites could see if it alters the outcome, we might learn something. Thanks.

(function(){

function identical(x, y) { if (x === y) { // 0 === -0, but they are not identical return x !== 0 || 1/x === 1/y; } else { // NaN !== NaN, but they are identical return isNaN(x) && isNaN(y); } }

Array.prototype.indexOf = function(specimen) { var len = this.length; for (var i = 0; i < len; i += 1) { if (identical(this[i], specimen)) { return i; } } return -1; };

Array.prototype.lastIndexOf = function(specimen) { for (var i = this.length; --i >= 0; ) { if (identical(this[i], specimen)) { return i; } } return -1; }; })();

# Waldemar Horwat (17 years ago)

Mark S. Miller wrote:

The indexOf and lastIndexOf methods are new in ES3.1, and are the only methods in the entire spec that depend on ===.

Strictly speaking that's true, but only because the switch statement is not a method. switch statements depend on ===.

Waldemar
# Igor Bukanov (17 years ago)

2008/11/11 Waldemar Horwat <waldemar at google.com>:

Mark S. Miller wrote:

The indexOf and lastIndexOf methods are new in ES3.1, and are the only methods in the entire spec that depend on ===.

Strictly speaking that's true, but only because the switch statement is not a method. switch statements depend on ===.

There was a recently reported bug for SpiderMonkey where the implementation treated -0 as not equal to 0 for some optimized switch cases. Given that the bug was present in the code at least since 1998 this gives indications that even for a switch a change to use Object.identical, not ===, could be compatible with the web.

, Igor

# Mike Cowlishaw (17 years ago)

The indexOf and lastIndexOf methods are new in ES3.1, and are the

only

methods in the entire spec that depend on ===.

Strictly speaking that's true, but only because the switch statement

is not

a method. switch statements depend on ===.

There was a recently reported bug for SpiderMonkey where the implementation treated -0 as not equal to 0 for some optimized switch cases. Given that the bug was present in the code at least since 1998 this gives indications that even for a switch a change to use Object.identical, not ===, could be compatible with the web.

Igor, that may (or may not) be helpful. 'equal to' has many interpretations. Do you mean "numerically equal to"? In which case the mathematical interpretation of the strings "-0", "0.00", "-0e16234" and "0000000000" are all the same. But in the real world, "drive for 10.3 miles and then turn left", "drive for 10.0 miles and then turn left", "drive for 10 miles and then turn left" lead to quite different driver behaviors.

mfc

Unless stated otherwise above: IBM United Kingdom Limited - Registered in England and Wales with number 741598. Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU

# Allen Wirfs-Brock (17 years ago)

Now that this is pointed out the case that bothers me is code that looks something like this:

switch (num) { case NaN: alert("NaN"); case +Infinity: case -Infinity: alert("Infinity"); default: alert("a fine old number"); }

The intent of the code is obvious and yet the NaN case is obviously a bug. However, I suspect that very view JavaScript programmer even among those who understand what a NaN is realize that.

I'd call this an attractive nuisance that should be fixed in the language specification, probably by changing switch to use Mark's SameValue test.

# Allen Wirfs-Brock (17 years ago)

Ugh, I guess I left out a couple breaks...