-
-
Notifications
You must be signed in to change notification settings - Fork 5.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
add issetequal and make hash/== generic for AbstractSet #25368
Conversation
I will mark this for triage. Technically, only |
base/set.jl
Outdated
⊇(l, r) = issubset(r, l) | ||
⊉(l::Set, r::Set) = !⊇(l, r) | ||
⊋(l::Set, r::Set) = <(r, l) | ||
const issubset = ⊆ |
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.
For all other unicode aliases, the ASCII name is the core function name, so this should be reversed.
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.
OK I understand, I just did it so that the printing of ⊆
and ⊇
gets more consistent.
true | ||
``` | ||
""" | ||
issetequal(l, r) = length(l) == length(r) && l ⊆ 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.
I think this should be the implementation for ==(::AbstractSet, ::AbstractSet)
; then we don't need issetequal
.
👍 to the basic set equality and hashing change, and I would vote for the version without |
💯% agree with Jeff – this would be good minus the |
base/set.jl
Outdated
# (if needed, only their synonyms issetequal, ⊊ and ⊆ must be specialized) | ||
==(l::AbstractSet, r::AbstractSet) = issetequal(l, r) | ||
<( l::AbstractSet, r::AbstractSet) = l ⊊ r | ||
<=(l::AbstractSet, r::AbstractSet) = l ⊆ 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.
I don't think the definition is correct. I think it's instead: for sets A
and B
, A < B
if ∀ a . A, ∀ b . B, a < b
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.
If I'm not mistaken, I changed nothing to the definition of <=
for sets. Do you suggest we should open a separate issue to change the meaning of (or delete) these methods?
The goal of |
OK, that makes sense, but the preferred function to implement should always be
(since hopefully we can assume Do you have an actual use for |
I agree this seems better, even if there can be a small drawback in some cases (as mentioned in the OP).
There will be a generic implementation, duplicated from
I don't remember if I needed it, but I find it strange to have all these set-related functions available (like I updated the PR according to your review and added NEWS. |
d3302c3
to
093cf45
Compare
093cf45
to
08a3a30
Compare
Thanks for making those changes; looks very good now. Might need to be rebased around the logging issue. |
08a3a30
to
029ce68
Compare
This is a fix for #25318. It implements a generic
issetequal
binary predicate which tests whether two collections have the same elements. Moreover, it defines==(::AbstractSet, ::AbstractSet)
andhash(::AbstractSet)
generically so that two sets compare and hash equal. As noted in the issue, this makeshash
significantly slower forBitSet
(by about 6x, i.e. more or less as "slow" as forSet
), but it's probably not a big deal.In the current state,
issetequal
,⊆
, and⊊
are the "primary" functions, which are the ones to be specialized if needed, and==
,<=
and<
are aliases for those. I chose so as it makes the implementation simpler:issetequal
,⊆
, and⊊
have to be defined both for generic collections and forAbstractSet
==(::MySet, ::AbstractSet)
andissetequal(::MySet, itr)
depending on whether the other argument is a set (and similarly for the other 2 functions). It seems simpler to only have to specialize one functions in all cases, (which can also share the same implementation whatever the second argument is,AbstractSet
or not).But it's possibly ugly for a set type to specialize
issetequal
instead of==
.Note that the generic implementation of
issetequal(a, b)
currently requireslength(a)
andlength(b)
to exist, but this could be lifted in the future.