-
-
Notifications
You must be signed in to change notification settings - Fork 14.5k
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
lib.lists.allUnique: init #239722
lib.lists.allUnique: init #239722
Conversation
84be328
to
314575e
Compare
734f897
to
ffa0fd7
Compare
I must admit that I'm a bit confused by what the |
@pennae are you fine in only providing the |
not so much. almost all other sort-like list operations have a generic variant (the notable exception being
not sure how filtering even figures here. |
ffa0fd7
to
ba0d5c2
Compare
@pennae If we would filter the list and only look for uniqueness in a subset of the list this makes sense to me. But sorting based on a predicate and then check if the previous is equal does not really make sense to me. fyi: my main motivation is to have the function |
genericism.
not sure we understand the question, but "list contains duplicates" and "two adjacent equal elements in sort order exist" are the same thing.
if you filter anything at all you can no longer check uniqueness though? filtering a list literally means dropping things from it, invalidating the entire idea of checking the original for any kind of uniqueness?
and we don't want to stop that function existing. but limiting it to things that are directly |
how are we going to continue here? |
We shouldn't merge functions that have no use case. If So I don't think we should have I also want to point out that #119286 also tried to introduce a I do however think that we need a better name. Currently we only have
The
This would then lead to an inconsistent library where So instead we should probably have functions like these:
We could also deprecate
And then you could also think of how the |
ping @bb010g for continuing the discussion. @infinisil I am not a huge fan of naming functions according to their runtime, because no function is named like this yet. What do you think about:
any thoughts? |
I like the idea, how about:
This indicates that "It first sorts it, then does makes elements unique". Although then we run into another inconsistency: So, I think |
ba0d5c2
to
4a438a9
Compare
lib/lists.nix
Outdated
*/ | ||
sortUnique = lst: | ||
let sortedList = lib.sort builtins.lessThan lst; in | ||
(lib.foldl' (acc: e: {r = if e != acc.last then acc.r ++ [ e ] else acc.r; last = e;}) {r = []; last = (dummy: 0);} sortedList).r; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@infinisil not sure if this is the perfect way... This is the first idea that came to my mind.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something like findFirst id false (zipListsWith (fst: snd: fst != snd) sortedList (drop 1 sortedList))
might be nicer
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry, but I am unable to get this to work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm you're right this doesn't work. And refactoring your implementation I'm noticing that there's a ++ [ e ]
in a loop, which actually makes this still an
All a user needs to know is which comparison method is used, and that implementations that are restricted to
However, these functions seem to be comparisons.
|
I agree with your point, however usually the more specific method with the more specific name is expected to have better performance. So maybe How difficult would it be to have only one function which automatically does the right thing depending on the data? I don't know how expensive a O(n) data walk to check is in practice, but maybe one could implement it such that it starts with sorting and falls back to the other as soon as it encounters non-comparable data? |
I have the opposite expectation, so I guess we better make it explicit then; both
Not sure what type would actually need |
A version of
As mentioned earlier, we already have allUnique = list:
list == unique list Which wouldn't be the case. |
so you all agree to the naming of the functions? or are there any objections? |
I'd like @roberth to reconsider #239722 (comment). And in any case, it's better to have more verbose names first, we can still introduce shorter aliases later if it becomes clear how they should behave. |
reminder @roberth . |
any chance this will get merged into 23.11? |
Suggestion:
That avoids @roberth's concern regarding |
lib/lists.nix
Outdated
*/ | ||
sortUnique = lst: | ||
let sortedList = lib.sort builtins.lessThan lst; in | ||
(lib.foldl' (acc: e: {r = if e != acc.last then acc.r ++ [ e ] else acc.r; last = e;}) {r = []; last = (dummy: 0);} sortedList).r; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something like findFirst id false (zipListsWith (fst: snd: fst != snd) sortedList (drop 1 sortedList))
might be nicer
acdb8e3
to
5abae15
Compare
8e29780
to
0153376
Compare
Sorry for all of the different opinions and the long discussions @Stunkymonkey. Since I'm not quite sure about the sort variants (see #239722 (comment)), and you really only needed |
0153376
to
66261e9
Compare
thanks @infinisil for pointing this out. Small steps is better then no steps at all. I just remove the unneeded code. Please have a look. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice!
Description of changes
The intention is to write easier and better assert like check port-allocation, subdomains, ...
there have been a suggestions in the matrix channel to expose
countValues
to other functions.I think this is not a good idea, because the key is converted to a string, which makes it not really reuseable.
Except for assert messages maybe.
Things done
sandbox = true
set innix.conf
? (See Nix manual)nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD"
. Note: all changes have to be committed, also see nixpkgs-review usage./result/bin/
)