ProtoObject and comparison for equality and ordering

Eduard Staniloiu edi33416 at gmail.com
Tue May 14 20:36:08 UTC 2019


On Tuesday, 14 May 2019 at 20:07:08 UTC, Andrei Alexandrescu 
wrote:
> On 5/14/19 4:00 PM, Adam D. Ruppe wrote:
>> On Tuesday, 14 May 2019 at 19:34:12 UTC, Andrei Alexandrescu 
>> wrote:
>>> In designing ProtoObject
>> 
>> I think ProtoObject should define *absolutely nothing*.
>
> That is the case regardless. The question is whether the global 
> __cmp accepts ProtoObjects.

Adding some more context to this

The current design proposal states that we will have an empty 
ProtoObject as the root of all classes and interfaces that define 
what behaviours implementing types can achieve.

The proposed design for the Ordered interface is
```
interface Ordered
{
     const @nogc nothrow pure @safe scope
     int opCmp(scope const ProtoObject rhs);
}
```

Any class type that desires to be comparable should implement 
Ordered.
The reason why `Ordered`'s `opCmp` takes a `ProtoObject` is, as 
Andrei said, that there might
be some cases where we would have lost all compile time 
information and we are comparing two `ProtoObjects`. This 
interface solves this issue, but at the cost of imposing the 
function attributes on the user, instead of inferring them.

Jonathan's question got us to the point raised: maybe it doesn't 
make much sense to be able to compare two `ProtoObjects`, so 
maybe you shouldn't be able to. This would change the interface to
```
interface Ordered(T)
{
     int opCmp(scope const T rhs);
}
```

Now the attributes of `opCmp` will be inferred. The implication 
of this is that now, if we are in the worst case scenario 
(comparing two `ProtoObject`s) we can not establish any 
relationship between the two, the `__cmp` lowering won't be able 
to compare two.
This implies that the cast (runtime downcast or compile-time 
cast) will be moved at the call site, in the hands of the user; 
which might be the right thing to do.

Since we are here, I want to raise another question:
Should `opCmp` return a float?

The reason: when we attempt to compare two types that aren't 
comparable (an unordered relationship) we can return float.NaN. 
Thus we can differentiate between a valid -1, 0, 1 and an invalid 
float.NaN comparison.

Cheers,
Edi


More information about the Digitalmars-d mailing list