Skip to content
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

[Question/Proposal] Support for == and != on ValueTuple #13155

Closed
OzieGamma opened this issue Aug 14, 2016 · 6 comments
Closed

[Question/Proposal] Support for == and != on ValueTuple #13155

OzieGamma opened this issue Aug 14, 2016 · 6 comments

Comments

@OzieGamma
Copy link

Following this PR: dotnet/corefx#10417
And these issues: https://github.com/dotnet/corefx/issues/10416, dotnet/corefx#10417

It seemed like support for == and != on ValueTuple might be needed. I don't know if the compiler already supports this ?

If not @gafter mentioned support for this should be in the compiler not in corefx.

I have two main concerns with adding operator== and operator!= to System.ValueTuple. Both of them boil down to the assertion that these operators should act as if operating using == on the underlying elements. But you can’t program that into the ValueTuple type, because the implementation of the generic type doesn’t know what operator== to apply to the elements. For example

  1. Using object.Equals(x, y) isn’t correct, because it isn’t the same as operator==. To take an example from our platform, double.NaN.Equals(double.Nan), but !(double.NaN==double.NaN). So (double.NaN == double.NaN) would give a different result from ((double.NaN, 0) == (double.NaN, 0)) if we implement the latter using object.Equals(); the former would be false while the latter would be true. I believe that is not what we want.
  2. We would want the == operator on tuples to apply whenever an underlying operator== can be found to apply on the elements, pointwise. If we do it in the language+compiler (now or in the future), we can make ((long)1, (byte)2) == ((short)1, (int)2) be true (not a compile-time error because no operator== can be found). However, there is no way to express that in source.

In short, I believe that adding support for operator== and operator!= to the sources of the ValueTuple libraries would be locking us in to the wrong semantics for what we would want the behavior to be.

@HaloFour
Copy link

I agree, I think that the compiler should compare the elements in the tuples directly to one another as if there is no tuple:

(Foo, Bar) tuple1 = ...;
(Foo, Bar) tuple2 = ...;

if (tuple1 == tuple2) { ... }
// equivalent to writing:
if (tuple1.Item1 == tuple2.Item1 && tuple1.Item2 == tuple2.Item2) { ... }

That way, as mentioned, the compiler can take advantage of overloading equality operators as well as implicit conversions.

Assuming that Roslyn goes in that direction, how would it compare two tuples where the named elements are in different order but would otherwise be the same?

var tuple1 = (first: "John", last: "Smith");
var tuple2 = (last: "Smith", first: "John");

bool equals = (tuple1 == tuple2); // ?

@alrz
Copy link
Member

alrz commented Aug 14, 2016

@HaloFour I think names are just for convenience. Tuples, by definition, are just some ordered values. So I'd say that names shouldn't affect equality etc.

@AlexanderTaeschner
Copy link

@HaloFour,@alrz I would expect a warning for this comparision and then a result of false, since ("John" == "Smith") && ("Smith" == "John") = false.

@AdamSpeight2008
Copy link
Contributor

AdamSpeight2008 commented Nov 6, 2016

Adding support for the operators = and != for ValueTuple I think would very useful
As it enable a very simple version of constant expression pattern matching, especially if the tuple consists of the core system types.

Select Case (ch, nx)
  Case ((True, "{"c), (True, "{"c))
    ' Escaped Opening Brace
  Case ((True, "}"c), (True, "}"c))
    ' Escaped Closing Brace
End Select

Edit: It feels very natural fit for VB.net (at least)

@jcouv
Copy link
Member

jcouv commented Feb 23, 2017

One scenario was mentioned in LDM about this:

(T, int) tuple = M();
if (t == (null, 0)) ...; // there is some target-typing happening here for null

We'd want this to work, since the same code without tuples works: T x = M(); if (t == null) ...;

@jcouv
Copy link
Member

jcouv commented May 14, 2017

I'll close this issue from the compiler repo. The discussion was moved to csharplang repo: dotnet/csharplang#190

@jcouv jcouv closed this as completed May 14, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants