Optional auto-generation of operator== and hashCode on classes with const constructors

114 views
Skip to first unread message

kc

unread,
Aug 25, 2016, 11:32:59 AM8/25/16
to Dart Misc

The Flutter team raised this - as have many folks on this group (who have some modicum of taste when it comes to language design).

Is this going anywhere? The github conversation just petered out.

K.

Lasse R.H. Nielsen

unread,
Aug 26, 2016, 3:00:42 AM8/26/16
to mi...@dartlang.org
For this to be viable, it must be triggered by user request. Something like `bool operator==(Object other) auto;` (or, preferably, something less ugly) and ditto for hashCode.

We can't just add an equality that is based on field equality. That might just be wrong, even for a class with a const constructor and final fields. Equality is a logical property, not a physical one, you need to know the interpretation of the object to know whether to use equality or identity for the fields, and whether some fields are not part of the equality.

I don't see us doing this for class types. It might (but only maybe) make sense for some sort of value types - but not necessarily for all "value type" designs.

/L

--
For other discussions, see https://groups.google.com/a/dartlang.org/
 
For HOWTO questions, visit http://stackoverflow.com/tags/dart
 
To file a bug report or feature request, go to http://www.dartbug.com/new
---
You received this message because you are subscribed to the Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to misc+uns...@dartlang.org.



--
Lasse R.H. Nielsen - l...@google.com  
'Faith without judgement merely degrades the spirit divine'
Google Denmark ApS - Frederiksborggade 20B, 1 sal - 1360 København K - Denmark - CVR nr. 28 86 69 84

Günter Zöchbauer

unread,
Aug 26, 2016, 4:26:36 AM8/26/16
to Dart Misc
Some annotation to mark the properties relevant for equality

struct {
  @identity int a;
  @identity String b;
  String x;

Lasse R.H. Nielsen

unread,
Aug 26, 2016, 4:42:55 AM8/26/16
to mi...@dartlang.org
On Fri, Aug 26, 2016 at 10:26 AM, Günter Zöchbauer <gzo...@gmail.com> wrote:
Some annotation to mark the properties relevant for equality

struct {
  @identity int a;
  @identity String b;
  String x;
}

If you use annotations, then it's not really part of the language, and what you are asking for is basically a preprocessor to generate the equality/hashcode.
That's perfectly doable already. 

If we want it to be *in* the language, then we could do something like:

  auto operator == :: <MyType>(foo, bar, baz:identical);
  auto get hashCode :: (foo, bar, baz: identitiyHashCode);

which is defined to expand to:

  bool operator ==(Object other) => other  is MyType && this.foo == other.foo && this.bar == other.bar && identical(this.baz, other.baz);
  int get hashCode => (new Hasher()..add(this.foo.hashCode)..add(this.bar.hashCode)..add(identitiyHashCode(this.baz))).hash;

Still not brilliant syntax, but it allows you to declare what you want to do in a briefer way, but it doesn't happen automatically.

I'm not convinced it's worth it for normal classes. Value types, maybe.

/L

David Morgan ☯

unread,
Aug 26, 2016, 8:21:24 AM8/26/16
to Dart Misc
I tried to explain on the bug, but since you asked I will try again here :)

Note, I'm not on the Dart team, so please take this as opinion. I do however have a lot of experience with implementing tools that do this kind of generation, and they have significant use inside google. I'm currently building open source equivalents of these tools, of which https://github.com/google/built_value.dart is most relevant to this question.

So, with that said. The problem of operator== and hashCode:

1) Is easy to solve with codegen, as in built_value.dart. If all you want is operator== and hashCode then you can probably do this in a day.
2) Is hard to solve as a language feature. There are too many options. Why stop at operator== and hashCode, why not also toString? What about serialization? At some point you're likely to want codegen anyway, and then you could have easily taken care of operator== and hashCode.

So I really think it doesn't make sense to ask for a language feature. The focus right now should be on codegen. Any language feature requests right now should be about improving the codegen story.

It _might_ make sense to promote a popular codgen-based solution to a language feature, but only if it's used by such a huge proportion of Dart developers that it's clear it belongs in the language. That's not going to happen for a long time. And it's not going to happen at all unless people explore the codegen options.

Cheers

Morgan

kc

unread,
Aug 26, 2016, 9:05:59 AM8/26/16
to Dart Misc
Not looking for a debate on this group. Because debates on here go nowhere.

Rather are folks within Google working *collaboratively* on it. The github conversation died out aimlessly in a manner all to familiar to anyone who followed Dart 1.x.

K.

kc

unread,
Aug 26, 2016, 9:28:57 AM8/26/16
to Dart Misc
Have you guys - Dart, Fuschia/Flutter, Angular/Ads - considered holding a workshop to nail down these issues (as part of Dart 2.0).

I'm easy on a solution as long as the result is a Google consensus giving a good dev experience and a good user experience re performance.

K.

David Morgan ☯

unread,
Aug 26, 2016, 9:50:58 AM8/26/16
to Dart Misc
I'm afraid nobody is working on a language feature or trying to make a language feature happen.

I understand your frustration, it sounds like it would be a great thing to have. But the details are hard, and we already have a solution that works. If you want to influence or contribute to that solution, please look at the codegen possibilities.

Lasse R.H. Nielsen

unread,
Aug 26, 2016, 10:09:13 AM8/26/16
to mi...@dartlang.org
I'll have to agree with David Morgan.
There is no simple and generally applicable solution to automatically generating equality/hashCode.
I, for one, would never put a runtimeType check into the equality, but others ask for exactly that feature. 
It seems that what you really need is a way to specify how you define equality, in a domain specific language where you can describe it more concisely than just writing the code, and then have the equality/hashCode generated for you. That's not great as a language feature - we don't want a highly specialized sub-language just for that - and the generalization of it is something like macros, which is not a likely feature (again, it would be another sub-language that you have to read in order to read Dart, it's not just S-expressions like in Scheme).
So, unlikely as a language feature on normal classes. If we get value-types of some sort, it might make more sense, but that depends entirely on how they work out. It's entirely too soon to say anything specific, even whether value types will exist at all.

That comes back to code generation. Something like that exists already, e.g., in the built-values package, but the fact that they don't do what everyone wants is just another proof that there isn't one universal solution. If you have specific needs, you need specific tools to fulfill them.

So, no current plans for auto-generated equality on classes as a language feature.
/L






--
For other discussions, see https://groups.google.com/a/dartlang.org/
 
For HOWTO questions, visit http://stackoverflow.com/tags/dart
 
To file a bug report or feature request, go to http://www.dartbug.com/new
---
You received this message because you are subscribed to the Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to misc+uns...@dartlang.org.



--
Lasse R.H. Nielsen / l...@chromium.org

tatumizer-v0.2

unread,
Aug 26, 2016, 11:42:29 AM8/26/16
to Dart Misc
> That's not great as a language feature - we don't want a highly specialized sub-language just for that - and the generalization of it is something like macros, which is not a likely feature (again, it would be another sub-language that you have to read in order to read Dart, it's not just S-expressions like in Scheme).

There's a systematic way to expand a language- use annotations. Actually, many languages do that - some annotations are interpreted by compiler (e.g. in swift; though they use term "attributes" instead of "annotations", but it's the same syntax). They are pretty powerful - not as powerful as S-expressions, but still...
Otherwise, language will soon get stuck for purely syntactic reasons. Self-inflicted wound.

kc

unread,
Aug 27, 2016, 9:43:28 AM8/27/16
to Dart Misc
I liked your work and thinking on builders/values. Seems pretty core to where things are going re React/Flutter/Rosyln. 

Frustration comes from the perception that consensus hasn't been reached *within* Google which leads to confusion for users *outside* of Google.

K.

kc

unread,
Aug 27, 2016, 9:52:21 AM8/27/16
to mi...@dartlang.org
On Friday, August 26, 2016 at 3:09:13 PM UTC+1, Lasse Reichstein Holst Nielsen wrote:
I'll have to agree with David Morgan.
There is no simple and generally applicable solution to automatically generating equality/hashCode.
I, for one, would never put a runtimeType check into the equality, but others ask for exactly that feature. 
It seems that what you really need is a way to specify how you define equality, in a domain specific language where you can describe it more concisely than just writing the code, and then have the equality/hashCode generated for you. That's not great as a language feature - we don't want a highly specialized sub-language just for that - and the generalization of it is something like macros, which is not a likely feature (again, it would be another sub-language that you have to read in order to read Dart, it's not just S-expressions like in Scheme).
So, unlikely as a language feature on normal classes. If we get value-types of some sort, it might make more sense, but that depends entirely on how they work out. It's entirely too soon to say anything specific, even whether value types will exist at all.

The idea of the interface to the runtime not being source (Dart/JS/Python) or byte code (JVM/dotnet) but an annotated Abstract Syntax Tree has been mooted. Like WASM - but at a higher more dynamic level. Then the language becomes a kind of macro/dsl.

K.

DoHyung Kim

unread,
Aug 28, 2016, 1:23:30 AM8/28/16
to Dart Misc
To me, it looks quite similar to data class in Kotlin and case class in Scala in spirit. Scala's case class is somewhat tied to its pattern matching facility. C# 7's record type seems also quite much in the same vein as the Scala case class. But Kotlin's data class only supports simple destructuring and I found myself not use it so frequently (though I've not coded in it long enough).

Such autogeneration feels somewhat adhoc if it's not tied to something significant like pattern matching, IMO. There are plenty of things to benefit from autogeneration and not all of them can be covered by the language proper.

DH

2016년 8월 26일 금요일 오전 12시 32분 59초 UTC+9, kc 님의 말:

Alex Tatumizer

unread,
Aug 28, 2016, 9:33:01 AM8/28/16
to mi...@dartlang.org
> There are plenty of things to benefit from autogeneration and not all of them can be covered by the language proper.
It seems there's a syntactic form that can trigger autogeneration in this and some other cases.
It looks (tentatively) as Comparator<T>(listOfFieldsForEqality) e.g. Comparator<Point>([#x, #y]). There's enough information in this "constructor call"
for compiler to autogenerate everything we need.
Please see my post in
Reply all
Reply to author
Forward
0 new messages