-
Notifications
You must be signed in to change notification settings - Fork 182
Undocumented change to Set.from{Asc,Desc}List
in containers-0.8
?
#1118
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
Comments
Uh oh. That's not good. Does anyone know where the change was introduced? It may have been an accident. |
That is correct. I do not want to document and commit to this behavior (as I wrote in #1032 (comment)), which is why I did not add a changelog entry for it. Map and Set functions currently do not specify what happens when keys compare equal but aren't really equal (#587). This situation could be improved if someone figures out a reasonable convention to be applied throughout, but I think piecemeal fixes to specify the current behavior will just be confusing. Until then, it is best to leave it unspecified. Since |
@meooow25 , I thought we had documentation for at least some functions that indicates the behavior in these cases. Or is that only for |
Yes I recall seeing it for Data.Set.intersection, but I did not check why it was added there. For Map we do specify which value is kept if the same key maps to different values which are combined in some way, but we do not specify the behavior for keys. |
@meooow25 Many thanks for commenting on this—I really appreciate it. I can definitely understand the preference to keep this unspecified. Perhaps this an example of Hyrum's Law 😄?
Having said that, I noticed that
Do you think it would be worth adding a similar disclaimer to the documentation for Perhaps something like:
|
It's certainly possible😄, but I would call a change "breaking" only if it breaks the behavior promised in the contract.
Personally I wouldn't mind if it said that. But one could argue that the same disclaimer should be added to every function with this issue, which seems like a step too far given that there are many of them and we haven't taken a stance on the right behavior for them. (btw sorry it took a while to respond, I took a break to focus on other things) |
Set.from{Asc,Desc}List
in containers-0.8
?Set.from{Asc,Desc}List
in containers-0.8
?
Set.from{Asc,Desc}List
in containers-0.8
?Set.from{Asc,Desc}List
in containers-0.8
?
My apologies -- I've adjusted the title of this issue to remove "breaking".
That's a fair point. Do we know how many functions this actually affects? Looking over the
That leaves the following functions currently without an explicit statement:
We could clarify intentions about their behaviour with statements like:
Justification: Since some functions already describe their de-duplication strategy while others don't, it might not be obvious to users whether this difference is intentional. This could lead to incorrect assumptions about which elements are preferred, based on similar statements made for other functions. Perhaps adding explicit "no guarantee" statements would resolve this inconsistency and help to clarify the intended behaviour for users? This could also serve as a record of the current policy for those reviewing/maintaining the source code.
No worries -- I hope you were able to enjoy your break! |
Oh, we already have an inconsistency 🤦
This may be the list for Set, but recall that Map has the same problem with keys (#587).
That's a good point.
Sure, let's go with that, I'll get off the fence. It's a mess, but at least it will be a well-documented mess. |
👍🏻 Thank-you @meooow25 for considering this. I've created a PR here: #1127 Would definitely appreciate feedback -- particularly if anyone can think of a better way to word these statements! |
is the meaning of "duplicate" clear enough? If the element/Key type is polymorphic (not Int), there could be non-standard Eq/Ord instances. I think that current implementation only uses Ord, never Eq. Is this part of the API contract? Actually, I am surprised to find:
|
@jwaldmann wrote:
containers/containers/src/Data/Set/Internal.hs Line 1164 in f602764
Internally, it only uses containers/containers/src/Data/Set/Internal.hs Lines 1165 to 1172 in f602764
Of course, this only works if the precondition for As for Internally this repeatedly applies containers/containers/src/Data/Set/Internal.hs Lines 1672 to 1682 in f602764
|
Oh right, those types make sense. Still, they imply different meanings for "duplicate". I am not sure whether this needs to be spelled out in the docs. |
@jwaldmann Regarding:
I think this is a valid point. For
What we might write for One approach could be to explicitly state whichever function the implementation uses:
|
That seems fine to me, we don't need to spell it out further.
I think we can safely assume Eq and Ord instances agree on equality. While it's not a law, it is "expected to hold" according to Ord docs. |
Closing this given the Set behavior is now documented. (I'm still thinking about the bigger question) |
There seems to be a small difference in the behaviour of
Set.from{Asc,Desc}List
betweencontainers-0.7
andcontainers-0.8
, specifically when these functions are applied to lists with duplicate elements.containers-0.7
these functions keep the first of any duplicates.containers-0.8
these functions keep the last of any duplicates.I'm guessing the change was introduced in #1083, which fixes #1032.
As I understand it, this change makes the behaviour of
Set.from{Asc,Desc}List
more consistent with the equivalentMap.from{Asc,Desc}List
functions, which seems very reasonable!Though perhaps we could add something about this to the changelog for
0.8
? (Even though this behaviour was previously unspecified!)Perhaps something like this:
If people are happy with this wording (or similar), I'd be happy to create a PR to add it.
I ran into this while looking at
nonempty-containers
, which is affected by this change. See:containers-0.8
. mstksg/nonempty-containers#17 (comment)containers-0.8
. mstksg/nonempty-containers#17 (comment)I'm guessing that other downstream libraries could also be affected. (But I don't currently have other examples to share.)
The text was updated successfully, but these errors were encountered: