opEquals/opCmp returning other types

Timon Gehr timon.gehr at gmx.ch
Mon Mar 19 01:29:34 PDT 2012


On 03/19/2012 02:31 AM, H. S. Teoh wrote:
> On Mon, Mar 19, 2012 at 01:54:27AM +0100, Brian Palmer wrote:
> [...]
>> However, this won't work for comparison operators like<  and>, which
>> all map to opCmp, or for != (since that's rewritten to !(a == b))
>>
>> I guess I have two questions, one, am I going to shoot myself in the
>> foot by going down this path, because it only happens to work due to
>> the compiler being too lax? And is there interest in extending D to
>> allow the rest of the operators to return non-boolean results? I'm
>> thinking something like falling back to opBinary!("<"), etc, if opCmp
>> isn't defined for a struct.
>
> IIRC, the reason D chose to go with opCmp and opEquals rather than the
> C++ route of operator...() for each comparison operator is so that the
> language can give some guarantees about the consistency of a<b, a<=b,
> a==b, etc..
>

That is fine. Iff you want it.

> In C++, for example, you can define operator<() and operator>() in
> completely arbitrary ways, which means they can be totally unrelated to
> each other, and return results that have nothing to do with each other.

I can also write a program that behaves in an arbitrary way. I usually 
want it to do something useful though.

> This causes inconsistency in that a<b does not necessarily imply b>a,
> and vice versa.

I suppose you meant b>=a. But even then, that is already sometimes the 
case for built-in types.

> Which makes for inconsistent code.
>

This is dependent on the context.


   foreach(network; db["networks"].each) {
     writefln("network: %s", network.name);
     foreach(host; db["hosts"].where(db.c.id == network.id)) {
       writefln("\thost: %s", host.address);
     }
   }

vs.


   foreach(network; db["networks"].each) {
     writefln("network: %s", network.name);
     foreach(host; db["hosts"].where(db.c.id.less(network.id))) {
       writefln("\thost: %s", host.address);
     }
   }


This inconsistency is merely syntactical though and could be fixed using 
an 'equals' method instead of opEquals.


> By using opCmp in D, such inconsistency is avoided, and the user is
> spared the tedium of having to define operator<(), operator<=(),
> operator>(), operator>=(), (and in D, you also have to add !<=, !>=, !<,
> !>, etc.), ad nauseum; a single operator opCmp() takes care of all these
> cases.
>
>
> T
>

The current limitations make it impossible to define (for example) a 
floating point type with NaN that behaves like built-in float/double/real.





More information about the Digitalmars-d mailing list