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.



Reply via email to