ProtoObject and comparison for equality and ordering

Mike Franklin slavo5150 at yahoo.com
Tue May 14 20:37:53 UTC 2019


On Tuesday, 14 May 2019 at 19:34:12 UTC, Andrei Alexandrescu 
wrote:
> In designing ProtoObject and comparison for equality and 
> ordering, we've assumed all class objects are supposed to be 
> comparable (including ProtoObject themselves).

What's the rationale for that?  And are you talking about 
reference equality or value equality?

> That means code like this should always compile:
>
> bool fun(C, D)(C x, D y) if (is(C == class) && is(D == class))
> {
>    return x < y && x == y;
> }
>
> That is, any two class objects should be comparable for 
> equality (==, !=) and ordering (<. >, <=, >=). The decision 
> whether comparison actually works for the types involved is 
> deferred to runtime.

IMO, objects should only support reference equality out of the 
box.

> This is in keeping with Java, C#, and existing D where Object 
> has built-in means for comparison.

Classes in C# only support reference equality out of the box:  
https://dotnetfiddle.net/AOQ0Ry

> However the question Jonathan M Davis asked got me thinking -


> perhaps we should break with tradition and opt for a more 
> statically-checked means of comparison.

Yes, please.

> The drawback is that some objects would NOT be comparable, 
> which may surprise some users.

Not me.

> As a consequence, for example, creating hash tables keyed on 
> certain types will not work. This is not quite unheard of as a 
> type could disable opEquals. Also, by default struct types 
> cannot be compared for ordering - they must define opCmp.
>
> Should we go with a more statically-checked/imposed approach 
> with comparison, or stick with OOP tradition? Ideas welcome.

I don't agree that there is such a tradition, and even if there 
was, we should be questioning it.

I would like to distinguish between reference equality and value 
equality.  Reference equality, I think, should be done with the 
`is` operator, and should probably work out of the box. And I 
like the idea of users opting into any feature.  If users want to 
support value equality, they should implement `opEquals`.  If 
they want comparability they should implement `opCmp`.  If they 
want to support hashability, the should be required to implement 
a `getHash` or something along that line of thinking.

> The question is whether the global __cmp accepts ProtoObjects.

No, but it could accept something derived from `ProtObject` that 
has the necessary requisites, namely `opCmp`, which I believe can 
be checked statically.

Final thought.  Other languages don't have the 
design-by-introspection features that D has.  If they did, maybe 
they wouldn't have chosen the path they did.  D has an 
opportunity here to lead instead of follow.

Mike



More information about the Digitalmars-d mailing list