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

operator== only checks the generic type #15

Open
enetor opened this issue Sep 25, 2019 · 1 comment
Open

operator== only checks the generic type #15

enetor opened this issue Sep 25, 2019 · 1 comment
Labels

Comments

@enetor
Copy link
Contributor

enetor commented Sep 25, 2019

Current implementation of operator== checks the generic type instead of the parameterized type. For example:

class Tuple2<T1, T2> {
  @override
  bool operator ==(other) =>
      other is Tuple2 &&
      other.item1 == item1 &&
      other.item2 == item2;

What is the reason for not checking the parameterized type?

other is Tuple2<T1, T2>
@lrhn
Copy link

lrhn commented Jun 12, 2023

Just for posterity: I Cannot answer for the original authors, but most likely it's because the desired equality is actually element equality.
The typles are used as simple value types, and it would probably be surprising if you did:

var pair = Tuple2(1, 2);
Set<Tuple2<num, num>> set = {pair};
print(set.contains(Tuple2(1, 2)));

and it printed false. Which it would, becasue var pair = Tuple2(1, 2); has no context type, so it infers Tuple2<int, int>, which contains(Tuple2(1, 2)) has a context type of Tuple<num, num> and would therefore create an instance of that.

Tuples are immutable, so the optimal runtime type would be type arguments that were the runtime type of the elements. A Tuple2<num, num>(1, 2) is strictly less useful than a Tuple2<int, int>(1, 2), because the latter can be assigned to Tuple2<num, num> and then works fine at that type, but the former cannot be used as a Tuple2<int, int> at all.
(And that's what Dart 3.0's records do: Their runtime type is the record type of their fields' objects runtime type.)

So the class will allow you to give every tuple its optimal type arguments, but not punish you if it fails (not until you try a cast which won't work).
Using only the values for equality is allowing precisely that

Secondarily, if the type parameters were part of equality, they should probably also be part of hashCode, which means taking the hash code of reified Type objects.
It'd not be wrong to not include the types in the hash code, after all it's not incorrect for non-equal values to have the same hash code, but it would risk hash code conflicts, if a Tuple2<int, int>(1, 2) and Tuple2<num, num>(1, 2) ended up in the same hash set/map.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants