Consider the following code:
let compareFn = (a,b) => a - b
[Infinity, 9, 3, 4 , -Infinity, 6, Infinity, 2].sort(compareFn)
The behaviour of the `sort` method is left undefined by the spec, because the `compareFn` produce `NaN` instead of `0` in the following case:
compareFn(Infinity, Infinity)
However, four browsers I've tried (latest stable versions of Safari, Firefox, IE and Chrome) do produce the expected result in that particular example.
That case could be easily specified by allowing `compareFn(a, b)` to produce any number including `NaN`, and by requiring to treat `NaN` the same way as `0`.
fixed in rev26 editor's draft
in rev26
What if NaNs appear in the list to be sorted?
(In reply to Mark Miller from comment #3)
> What if NaNs appear in the list to be sorted?
Some experience with current browsers show inconsistent results (generally an incompletely sorted array).
js> [NaN, 4, 2, NaN, 1, NaN, 3].sort(function(a, b) { return a - b })
Safari 7: [NaN, 1, 2, 4, NaN, NaN, 3]
Firefox 31: [3, NaN, 1, NaN, 2, 4, NaN]
Chrome 36: [NaN, 2, 4, NaN, 1, NaN, 3]
IE 11: [NaN, 2, 4, NaN, 1, NaN, 3]
This is maybe nitpicking, but...
The change made in Rev. 26 has consisted of adding a special case for NaN in the SortCompare Abstract Operation algorithm (Section 22.1.3.24.1; step 17.d).
Now: In case `comparefn` produces `NaN` for some pairs of values, then `comparefn` is never a "consistent comparison function" (as defined in Section 22.1.3.24 Array.prototype.sort), and thus the behaviour of sort is still allowed to be "implementation-defined".
But actually, we are not interested whether `comparefn` is a consistent comparison function, but whether SortCompare (defined in Section 22.1.3.24.1 Runtime Semantics: SortCompare Abstract Operation) is "consistent".
However, since the change made in Rev.26, it is no longer the same thing for SortCompare or for `comparefn` to be consistent...
I think that the more elegant way to resolve the issue is as follows:
* Revert the change made in Rev. 26; that is, in the abstract operation SortCompare, remove the special-casing for NaN. That will effectively remove the discrepancy between the "consistence" of `comparefn` and the "consistence" of SortCompare.
* Change the definition of "consistent comparison function" by allowing NaN to denote the "equality"; more precisely, make the following changes in the text:
* "a =CF b means comparefn(a,b) = 0 (of either sign)"
==> "a =CF b means comparefn(a,b) is +0, -0, or NaN"
* "Furthermore, Type(v) is Number, and v is not NaN."
==> "Furthermore, Type(v) is Number."
In fact, the objection of Comment #5 may be applied to further cases, e.g. when the `compareFn` does not produce values of type Number. In that case, implementations have also a more well-defined behaviour than what is currently specced; see Bug #3137.
I'm reclosing this Bug because of that, and because it is superseded by Bug #3137. In case I'm finding a convenient formulation for "consistent" that handles more cases than "non-NaN numbers", I could open a new Bug.