Roslyn: [Question/Proposal] Support for == and != on ValueTuple

Created on 14 Aug 2016  路  6Comments  路  Source: dotnet/roslyn

Following this PR: https://github.com/dotnet/corefx/pull/10417
And these issues: https://github.com/dotnet/corefx/issues/10416, https://github.com/dotnet/corefx/pull/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鈥檛 program that into the ValueTuple type, because the implementation of the generic type doesn鈥檛 know what operator== to apply to the elements. For example

  1. Using object.Equals(x, y) isn鈥檛 correct, because it isn鈥檛 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.

1 - Planning Area-Language Design Feature Request New Language Feature - Tuples

Most helpful comment

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

All 6 comments

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); // ?

@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.

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

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.

vb.net 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)

One scenario was mentioned in LDM about this:
C# (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) ...;

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

Was this page helpful?
0 / 5 - 0 ratings