Skip to content

[Belt] Add List.sort #2666

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

Merged
merged 5 commits into from
Mar 28, 2018
Merged

[Belt] Add List.sort #2666

merged 5 commits into from
Mar 28, 2018

Conversation

zploskey
Copy link
Contributor

@zploskey zploskey commented Mar 21, 2018

Implements Belt.List.sort as specified in the issue.
Adds a couple of simple tests and an example.

Fixes #2586.

@zploskey
Copy link
Contributor Author

zploskey commented Mar 21, 2018

Apparently Array.prototype.sort() sorts everything like a string, and is what Js.Array.sortInPlace() is bound to. Although I could easily fix the test, I don't think that function is what we want to use here. It's unintuitive for a sort function give a result like [1; 3; 3; 37; 9]. Maybe better to use sortInPlaceWith (fun a b -> a - b). But the other behavior is fine if we're dealing with strings. Seems like we'll need break it down by type.

@chenglou
Copy link
Member

Oh no, definitely don't use Js.Array.sortInPlace. That behavior is famously confusing. Maybe SortArray.stableSortInPlaceBy? cc @bobzhang

@zploskey
Copy link
Contributor Author

I went ahead and adjusted it to use SortArray.stableSortInPlaceBy. I figure whatever solution we settle on will use a compare function.

@chenglou
Copy link
Member

The asymmetry between SortArray and List.sort is a little weird. I'm wondering how we should arrange these

@zploskey
Copy link
Contributor Author

What was the reasoning behind putting Sort functions on arrays in their own separate module?

@@ -692,6 +692,13 @@ let setAssocU xs x k eq =

let setAssoc xs x k eq = setAssocU xs x k (fun [@bs] a b -> eq a b)

let sort xs cmp =
let arr = ref (toArray xs) in
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why a ref needed here

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sortU/sort

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I'll add a sortU version. I think I was confused about whether I could use let and it still be mutated by the in-place sort. It works fine without the ref.

let sort xs cmp =
let arr = ref (toArray xs) in
begin
Belt_SortArray.stableSortInPlaceBy !arr cmp;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A.stableSortInPlaceBy -- it is already aliased in the beginning

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Belt_Array is aliased as A in this module. It doesn't have the sort functions from Belt_SortArray. Should Belt_SortArray be opened in Belt_Array?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fine then, sorry my mistake

Signed-off-by: Zach Ploskey <zach@ploskey.com>
Signed-off-by: Zach Ploskey <zach@ploskey.com>
@zploskey
Copy link
Contributor Author

I addressed the concerns and rebased on master so that all the tests run. I'm not sure why we're seeing a build failure on Travis. It builds fine for me locally. Somehow it can't find Belt_SortArray.cmj, but it just built it a few lines before. 🤷‍♂️

Signed-off-by: Zach Ploskey <zach@ploskey.com>
@zploskey
Copy link
Contributor Author

That seems to have worked. Let me know if there are any other concerns.

Signed-off-by: Zach Ploskey <zach@ploskey.com>
let arr = toArray xs in
Belt_SortArray.stableSortInPlaceByU arr cmp;
fromArray arr

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general, in belt, we should define sortU first and wrap sort like this

let sort xs cmp = sortU xs (fun[@bs] x y -> cmp x y)

The thing is in your sort, you are calling stableSortInPlaceBy instead of stableSortInPlaceByU which is slower

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. Thanks!

Signed-off-by: Zach Ploskey <zach@ploskey.com>
@bobzhang bobzhang merged commit 8a94c43 into rescript-lang:master Mar 28, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants