-
Notifications
You must be signed in to change notification settings - Fork 3.3k
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
Implement guard-safe MapSet.is_member/2
#13386
Conversation
4da37b9
to
5f25719
Compare
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'd like to hear the opinion of other Elixir members before merging. :)
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.
LGTM 💜
I thought about two possible alternatives but I think the original one is the best, just sharing them for the record:
Kernel.is_map_set_member
- avoids the need forrequire
and mirrorsis_map_key
, but keeping it scoped inMapSet
makes sense- Have a
Kernel.map_set/1
macro which could allow both construction and pattern-matching, e.g.map_set([1, 2, 3])
andmap_set([^elem]) = ...
=> confusing since the fact it is partial is not obvious
Didn't know this was a thing now! Co-authored-by: José Valim <jose.valim@gmail.com>
Co-authored-by: Andrea Leopardi <an.leopardi@gmail.com>
8fa491b
to
8459b05
Compare
61bc1a2
to
c2317be
Compare
It is probably not that relevant to most people, especially with the new type system coming up, but I think this probably breaks Dialyzer's "opaqueness" access rules and will cause bubbling up "this function will never return" warnings when used |
Hm, I do indeed get this warning when using this macro copy-pasted into a project:
|
Good point, we could use |
If this causes "bubbling up" edit: I tried to come up with code that causes more Dialyzer issues and failed. 🎉 So maybe when the opaqueness violation happens in pattern matching like here (and not when constructing or returning data), it doesn't affect Dialyzer that much |
It looks like Dialyzer does not bubble up |
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.
Just one suggestion and we can ship it :)
Co-authored-by: José Valim <jose.valim@gmail.com>
Suggestion accepted, and documentation of failure modes added! |
Closed questionsI think this PR as-is has answered the finer points:
Neutral questionsInsofar as how we actually do the At the end of the day, I'm happy to ship it with any variant. Remaining wartNo variant I've tried seems to prevent dialyzer from warning on accessing the underlying opaque type calls, which I don't love, as part of the goal of this PR was to enable folk to do membership testing in guards without worrying about the private underlying type... But a dialyzer warning is better than requiring folk to use the internal struct keys of |
To clairfy the dialyzer warning I am seeing, they are only when:
Other usages don't seem to warn. I'm learning I have more to learn about |
Co-authored-by: José Valim <jose.valim@gmail.com>
Co-authored-by: Jean Klingler <sabiwara@gmail.com>
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.
LGTM 💜
MapSet.is_member/2
I am sorry folks, but I am still not confident we should merge this. For example, there is no guarantee the most efficient MapSet implementation will always have a single map at the root. Therefore, I will close this. |
Per discussion on elixir-lang-core, this provides a guard-safe membership check for
MapSet
s without modifying the existingMapSet.member?/2
.