-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Proposal for tuple equality/inequality comparisons #967
Conversation
Hrmm... maybe it might be better to define it as: It would allow Thoughts? |
I bring it up because it seems conceptually simpler, and requires no usage of != and || in the translation. |
That might not technically behave the same way if the types of the elements within the tuple implement custom equality/inequality operators that aren't mirrors of each other for whatever reason. |
Why disallowing dynamic elements? Seems odd. I think if I do the transformation by hand, then dynamic equality will be used for those elements. Seems like compiler could do the same. |
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 think dynamic elements could/should just work.
@VSadov Dynamic is "infectious". If it is used for one subexpression, then the result of that subexpression is of type |
@HaloFour @CyrusNajmabadi doubles are a good example of why you cannot replace |
I still think that it's best to leave this to trait impls: you can only compare two tuples if all the elements are comparable, e.g. implement<T, U> Eq<T, U> for (T, U) where T : Eq where U : Eq {
static bool operator ==((T, U) left, (T, U) right)
=> left.Item1 == right.Item1 && left.Item2 == right.Item2;
} Sure it won't work for all tuple arities, but I think we can get by, just like Rust did: https://doc.rust-lang.org/std/primitive.tuple.html#trait-implementations |
@alrz this would mean tuple equality would have to be delayed until typeclasses/shapes/traits/concepts are implemented. |
Yes, still better than this whole specialized code in the compiler. I didn't find myself to be desperate about this feature as much as I am for ADTs and generators, and still here we are. That's my least concern regarding "when" we can have it. Probably next thing you might want to be specialized is |
@alrz I would want this to return |
Just a comparison of specializing a syntax vs. a feature that might take a few releases to come, I didn't mean the exact thing. |
@alrz this feature permits comparing a (int, int) to a (long, long). Your type class (not trait) implementation does not. |
@gafter I suppose the compiler can manage implicit conversions for operators as it does today: var x = implicitlyConvertibleToInteger == 0; Same works in Rust in a similar manner: numeric promotion is distributed over all tuple elements, so let x = (1, 2) == (1u64, 2u64); works as expected - calls the operator |
@alrz When comparing an |
@gafter You're right, |
proposals/tuple-equality.md
Outdated
- `new A(1)` | ||
- `new B(2)` | ||
- `new B(3)` | ||
- `new A(1)` |
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.
Isn't that supposed to be new B(4)
?
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.
Thanks. Corrected
Tagging @MadsTorgersen @dotnet/roslyn-compiler for review.
Update: I will update this proposal with input from Neal and Mads:
e
to a 2-tuple does not affecte == (x, y)
(ie. it fails)(x, y) == (1, "")
versus(x, y) == (1, null)
when there is an==
betweenx
andbyte
. The second one should clearly succeed since the tuple(1, null)
has no natural type, we can give it type(byte, string)
. But should the first one succeed too? (it does in my current prototype, but we'll have to figure out how to word this because the conversion from1
tobyte
only works on constants, but the tuple is not a constant). I should test(byte, string) t = ...
and(byte x, string y) = ...
in those cases too.Relates to championed issue #190