Proposal idea: descending sort

Temporal has a bunch of nice comparator functions like PlainDate.compare:

myDates.sort(PlainDate.compare);

So convenient!

But oh no, now I need to sort them in descending order instead of ascending:

myDates.sort((a, b) => PlainDate.compare(b, a));

What is this madness?? Did someone make a typo switching the order? Did they forget that you don't need arrow function thunks when passing callbacks? No, they are just doing what they have been forced into by a cold, cruel world. Writing software has become joyless again, mere toil where we strive against the unfathomable machine to exhort our desired results from its CPUs.

But! This tragedy could be fixed by introducing a switch, e.g.

myDates.sort(PlainDate.compare, { descending: true });
myDates.sortDescending(PlainDate.compare);

Ah yes, now that is some code that is understandable in a single glance. Dare I say it, that is art.


I don't have time to champion something like this myself, but if someone else wants to run with this, go for it!

3 Likes

This is pretty understandable:

myDates.sort(PlainDate.compare).reverse();

Besides, the meaning of "reverse" is totally obvious regardless of what the comparison function does. "Descending" becomes a misnomer when the comparison function itself defines descending order, e.g. myNames.sortDescending((a, b) => b.length - a.length)

2 Likes

How about arr.sortRight(PlainDate.compare) which will be match with reduceRight?

Btw I proposed built-in compare class method for rest primitives:

The "right" in reduceRight() has more to do with the original order of the array and which direction you iterate over it. Where sortDescending() does not "iterate" over the items in a defined "order". It requests that the resulting array be in reverse order, however the sorting implementation wants to do that.

2 Likes

I suppose, array.sortLast() as in findLast() would not be better. But as we are talking of reversing, it could be along the lines of

  • array.sortReversed()
  • array.sortInverse()
  • array.sortTail() (this might not be preferred due to this nomenclature not being used in the ecosystem yet to my knowledge)

I would very much prefer not to add another Array method for this. Rather add a Function method!

arr.sort(PlainDate.compare.flip())
arr.sort(PlainDate.compare.inverse())
arr.sort(Function.inverseComparison(PlainDate.compare))

Function composition is much more versatile.

Yeah, a function to reverse a comparison function is much more natural.

That's what Java and Rust do, for example.

Only problem is where to put it. Function.prototype is kind of a weird place though I guess it would work. But I also think we should have some more built-in comparison functions, like the standard numeric one, so maybe a new namespace like Compare? As in, array.sort(Compare.numeric) for ascend sorting by numeric order, array.sort(Compare.reverse(Compare.numeric)) for descending sort.

3 Likes

The number of times I've had to quickly write a test sort to remember whether I want b-a or a-b...

A Compare namespace would be great for a few other things too, like being able to chain comparisons for tie-breaking, or compare arrays lexicographically, or use a key function on the comparator. I've written that code a few times; it's small and easy, but would be nice to have pre-supplied.

I've been wanting to propose a String.compareByCodepoint but I suppose a Compare.stringByCodepoint would work just as well.