Stream: contributing

Topic: List.sortAscBy and List.sortDescBy


view this post on Zulip Luke Boswell (Aug 14 2024 at 07:15):

A question about https://github.com/roc-lang/roc/pull/6990, which implements the List.sortAscBy and List.sortDescBy builtins.

sortAscBy : List elem, (elem -> Num *) -> List elem
sortDescBy : List elem, (elem -> Num *) -> List elem

Sam raised a good question, and I'm not sure what the answer is. Looking for any ideas.

Is this really the right API? Since we have https://www.roc-lang.org/builtins/Num#compare, I think it would be better to use a a, a -> [LT, GT, EQ] comparator if possible.

view this post on Zulip Anton (Aug 14 2024 at 08:26):

Yeah, a, a -> [LT, GT, EQ] seems better for consistency.

view this post on Zulip Kilian Vounckx (Aug 14 2024 at 08:34):

I think rust has both. sortWith and sortWithField I think. If we choose one, we definitely should go with a, a -> [LT, GT, EQ] as it is more general and the other can always be defined in terms of it

view this post on Zulip Luke Boswell (Aug 14 2024 at 08:39):

So the question then is, do we still want the sortAscBy and sortDescBy then?

I'd be happy to close the PR.

view this post on Zulip Anton (Aug 14 2024 at 08:51):

I do like the clarity of sortAscBy, you don't have to carefully inspect the function that sortWith uses, you immediately know it's ascending.

view this post on Zulip Anton (Aug 14 2024 at 08:54):

Hmm, the original (elem -> Num *) API may be better after all, it makes this case really easy:

        testCompareFn : _ -> U8
        testCompareFn = \n ->
            when n is
                ONE -> 1
                TWO -> 2
                THREE -> 3
                FOUR -> 4
        List.sortAscBy [THREE, ONE, TWO, FOUR] testCompareFn |> List.map testCompareFn

view this post on Zulip Luke Boswell (Aug 14 2024 at 08:55):

Oh, wait -- are we thinking the API should be more like sortAscBy : List elem, (a, a -> [LT, GT, EQ]) -> List elem? I hadn't thought of that.

In that case, are we replacing List.sortWith with these two?

view this post on Zulip Anton (Aug 14 2024 at 08:57):

Oh, wait -- are we thinking the API should be more like

That's how I understood it, what did you have in mind?

view this post on Zulip Notification Bot (Aug 14 2024 at 08:57):

8 messages were moved here from #contributing > Casual Conversation by Luke Boswell.

view this post on Zulip Anton (Aug 14 2024 at 08:59):

In that case, are re replacing List.sortWith with these two?

Maybe, it would remove some doubt about which way you're sorting

view this post on Zulip Luke Boswell (Aug 14 2024 at 09:00):

For reference, this is what the original issue listed the API as.

view this post on Zulip Brendan Hansknecht (Aug 14 2024 at 15:43):

I would push for something like this:

sort: List elem -> List elem where elem implements Ordering
sortBy: List elem, (elem -> field) -> List elem where field implements Ordering
sortWith: List elem, (elem -> [ Lt, Eq, Gt ]) -> List elem

# Then the reversed versions:
sortReversed: List elem -> List elem where elem implements Ordering
sortByReversed: List elem, (elem -> field) -> List elem where field implements Ordering
sortWithReversed: List elem, (elem -> [ Lt, Eq, Gt ]) -> List elem

view this post on Zulip Anton (Aug 14 2024 at 15:50):

I could go with that

view this post on Zulip Luke Boswell (Aug 14 2024 at 20:59):

Just to clarify is (elem -> [ Lt, Eq, Gt ]) meant to be (elem, elem -> [ Lt, Eq, Gt ]) in the above?

And is Ordering the same as Sortable PR?

 Sort implements
     compare : a, a -> [LessThan, Equal, GreaterThan] where a implements Sort

view this post on Zulip Brendan Hansknecht (Aug 15 2024 at 00:25):

Yep and yep

view this post on Zulip Brendan Hansknecht (Aug 15 2024 at 00:26):

Should match Sort just wasn't sure what final naming we went with


Last updated: Jul 06 2025 at 12:14 UTC