Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Status of non-numeric _comparefn_ in Array.p.sort #2306

Open
jmdyck opened this issue Feb 13, 2021 · 0 comments
Open

Status of non-numeric _comparefn_ in Array.p.sort #2306

jmdyck opened this issue Feb 13, 2021 · 0 comments

Comments

@jmdyck
Copy link
Collaborator

jmdyck commented Feb 13, 2021

This issue concerns, in the context of Array.p.sort, a comparefn that (at least sometimes) returns NaN or a value that isn't a Number. For brevity, I'll call this a non-numeric comparefn.

In the definition of "consistent comparison function" (CCF), if you call comparefn and get the return value v, then one requirement is Type(v) is Number, and v is not NaN. Thus, a non-numeric comparefn cannot be a CCF, and the resulting sort order is implementation-defined.

On the other hand, we see SortCompare taking steps to ensure that, regardless of what comparefn returns, SortCompare returns a Number, and one that isn't NaN. So you might wonder why it would bother to normalize a case where we already know that the sort order is implementation-defined.

The definition of CCF has excluded non-numeric comparefn since ES 3. But ES 6 (ES 2015) added the steps in SortCompare to handle them. As the last entry in Annex E says:

Previous editions did not specify how a NaN value returned by a comparefn was interpreted by Array.prototype.sort. ECMAScript 2015 specifies that such as value is treated as if +0 was returned from the comparefn. ECMAScript 2015 also specifies that ToNumber is applied to the result returned by a comparefn. In previous editions, the effect of a comparefn result that is not a Number value was implementation-defined. In practice, implementations call ToNumber.

This suggests (fairly strongly) that the point of the changes was to allow the effect of a non-numeric comparefn to not be implementation-defined, and thus that CCF's exclusion of non-numeric comparefn should have been relaxed at the same time.

However, we can't simply drop CCF's requirement that Type(v) is Number, and v is not NaN, because the definition relies on comparing the return value to zero, which is only meaningful if it's a non-NaN Number. Instead I think the definition needs to define a function derived from comparefn (that normalizes its return like SortCompare does), and then express all the definition's requirements on the derived function: comparefn is a CCF if its derived function satisfies all these constraints. (Although, instead of requiring Type(v) is Number, and v is not NaN, you can just note that that's always the case for the return value of the derived function.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant