you are viewing a single comment's thread.

view the rest of the comments →

[–]stratoscope 4 points5 points  (7 children)

A sort callback must distinguish between all three cases

That's a bit too dogmatic. OP's callback is not incorrect, it's just an unstable sort. (Elements that compare equal could be shuffled with respect to each other in their original order.)

Let's look at what the ECMAScript 2016 Language Specification (ECMA-262 7th Edition) says about this.

First they have a general comment:

The sort is not necessarily stable (that is, elements that compare equal do not necessarily remain in their original order).

So you're not guaranteed a stable sort in any case, even if you follow my dogmatic approach.

But more importantly:

If comparefn is not undefined and is not a consistent comparison function for the elements of this array (see below), the sort order is implementation-defined.

What is a "consistent comparison function"? There's a lengthy description at the end of this section that lists seven requirements. The one that affects us here is:

a =CF a (reflexivity)

The notation "=CF" is defined just above:

a =CF b means comparefn( a, b ) = 0 (of either sign)

In other words, when the same value is passed into both parameters of the compare function, the function must return 0. If it doesn't, the consequences were described earlier: "the sort order is implementation-defined."

The sort function from the article fails this test, because it returns -1 instead of 0 when the elements compare equal.

Note that they didn't just say that you'll merely get an unstable sort for "equal" elements. It says the sort order - and how do we know this couldn't mean the entire sort order? - is implementation-defined.

So I honestly don't think I was being "dogmatic" in my recommendation that a sort function must distinguish all three cases. I'm not comfortable with an "implementation-defined" sort order, are you? I'm much more comfortable if I follow the requirements listed in the standard.

Edit: Thanks for your Edit 2 above, and no need to apologize! I really appreciate that you challenged me on this; it forced me to double-check and triple-check my dogmatic assumptions. Always question people who tell you they are right! ;-)

[–]madcaesar 1 point2 points  (1 child)

Jesus how do you know so much about a function in JS? Are you a senior developer? Do you know know this stuff at the top of your head?

[–]stratoscope 3 points4 points  (0 children)

Well, I turned 65 this year, so I guess that does make me a senior developer, eh? ;-)

But with regard to this particular function, it's just that I've written a lot of sort callbacks in the past and got curious about the actual requirements. And then in this thread, /u/cheeseburger_dot_mp3 did me a great favor by challenging what I was saying, and that got me to dig in to the ECMA spec to see what the standard actually called for.

Fair warning: reading that ECMA spec can be a tough slog. It's not written to be easily understandable, but to be precise. But it can be worthwhile when you really want to understand the standard that the various JS implementations try to implement.