## digitalmars.D - opLess and opGreater

• Patrick Horn (26/26) May 06 2004 Currently in D there is a opCmp function returning a -1 if less, 0 if eq...
• Derek Parnell (33/67) May 07 2004 If I understand what you are saying, it is that given two vectors 'a' an...
• Derek (12/42) May 07 2004 This is what I get when thinking while trying real hard to leave the off...
• J Anderson (8/18) May 07 2004 Exactly! I see opCmp for anything (including vectors) as a sorting tool...
• Norbert Nemec (19/57) May 07 2004 In the operator overloading was designed with the clear objective that
• J Anderson (4/6) May 07 2004 If its so rare then your should be satisfied with using a method instead...
• Stewart Gordon (16/19) May 07 2004
• Ilya Minkov (13/18) May 10 2004 Harrr. Where have you studied math? To compare vectors (just as any
Patrick Horn <phrh yahoo.com> writes:
```Currently in D there is a opCmp function returning a -1 if less, 0 if equal or 1
if greater.  But this does not apply to classes where there the less or greater
doesn't strictly return True or False.

Consider a class for a 3-dimensional mathematical Vector.
class vector {
double i,j,k
..
}

In this class, for two vectors a and b, comparing a < b does not work because
vectors can be both greater and less (a.i<b.i but a.j>b.j)
But the problem is that opCmp can only return 1, -1 or 0, but nothing in
between. opCmp *must* return an int to work, because the compiler must return a
boolean to the expression (a>b). Therefore, this function would be invalid:

vector opCmp (vector b) {
return vector((i>b.i)?1:((i<b.i)?-1:0), (j>b.j)?1:((j<b.j)?-1:0),
(k>b.k)?1:((k<b.k)?-1:0));
}

The solution would be to have a method such as:

vector opGreater (vector b) {
return vector(i>b.i, j>b.j, k>b.k);
}

But D should still support opCmp because it is correct in most cases.

So to support both, the compiler should parse (a>b) and call a.opGreater(b).
The Object.opGreater method would then return (a.opCmp(b)==1).

Then, if the class overloads opGreater, the compiler will use that one instead
and ignore opCmp for that class.
```
May 06 2004
Derek Parnell <derek psych.ward> writes:
```On Fri, 7 May 2004 06:52:53 +0000 (UTC), Patrick Horn wrote:

Currently in D there is a opCmp function returning a -1 if less, 0 if equal or
1
if greater.  But this does not apply to classes where there the less or greater
doesn't strictly return True or False.

Consider a class for a 3-dimensional mathematical Vector.
class vector {
double i,j,k
..
}

In this class, for two vectors a and b, comparing a < b does not work because
vectors can be both greater and less (a.i<b.i but a.j>b.j)
But the problem is that opCmp can only return 1, -1 or 0, but nothing in
between. opCmp *must* return an int to work, because the compiler must return a
boolean to the expression (a>b). Therefore, this function would be invalid:

vector opCmp (vector b) {
return vector((i>b.i)?1:((i<b.i)?-1:0), (j>b.j)?1:((j<b.j)?-1:0),
(k>b.k)?1:((k<b.k)?-1:0));
}

The solution would be to have a method such as:

vector opGreater (vector b) {
return vector(i>b.i, j>b.j, k>b.k);
}

But D should still support opCmp because it is correct in most cases.

So to support both, the compiler should parse (a>b) and call a.opGreater(b).
The Object.opGreater method would then return (a.opCmp(b)==1).

Then, if the class overloads opGreater, the compiler will use that one instead
and ignore opCmp for that class.

If I understand what you are saying, it is that given two vectors 'a' and
'b', then 'a' is said to be greater than 'b' if every element in 'a' is
greater than the corresponding element 'b'. And similarly for "less than"
and "equal to" tests. And so in the cases where there is a mixture of
comparisions ( eg. a[1] < b[1] and a[2] > b[2]) you can't use a simple
opCmp() result.

You might have to resort to this sort of thing...

// WARNING; code not tested, just indicative code only.
Vector a,b,c
Vector gtVector = new Vector(1,1,1)
Vector ltVector = new Vector(-1,-1,-1)
Vector eqVector = new Vector(0,0,0)
. . .
c = (a > b);
switch (c)
{
case gtVector:
// do Greater-Than processing
break;
case ltVector:
// do LessThan processing
break;
case eqVector:
// do Equality processing
break;
default:
// do mixed processing
break;
};

--
Derek
7/May/04 5:43:26 PM
```
May 07 2004
Derek <ddparnell bigpond.com> writes:
```On Fri, 7 May 2004 17:58:10 +1000, Derek Parnell wrote:

On Fri, 7 May 2004 06:52:53 +0000 (UTC), Patrick Horn wrote:

Currently in D there is a opCmp function returning a -1 if less, 0 if equal or
1
if greater.  But this does not apply to classes where there the less or greater
doesn't strictly return True or False.

[SNIP]

You might have to resort to this sort of thing...

// WARNING; code not tested, just indicative code only.
Vector a,b,c
Vector gtVector = new Vector(1,1,1)
Vector ltVector = new Vector(-1,-1,-1)
Vector eqVector = new Vector(0,0,0)
. . .
c = (a > b);
switch (c)
{
case gtVector:
// do Greater-Than processing
break;
case ltVector:
// do LessThan processing
break;
case eqVector:
// do Equality processing
break;
default:
// do mixed processing
break;
};

This is what I get when thinking while trying real hard to leave the office
on time! This is a *very-silly-idea*. Sorry people.

It would be easier to live with opCmp() and create your own opGreater() etc
functions for the vector class. Yes, that means you won't get " a < b "
calling it, but at least your code will work as you expect it to.

There are certain commly used vectors that opCmp() works perfectly for -
strings!

--
Derek
Melbourne, Australia
```
May 07 2004
```Derek wrote:

On Fri, 7 May 2004 17:58:10 +1000, Derek Parnell wrote:

This is what I get when thinking while trying real hard to leave the office
on time! This is a *very-silly-idea*. Sorry people.

It would be easier to live with opCmp() and create your own opGreater() etc
functions for the vector class. Yes, that means you won't get " a < b "
calling it, but at least your code will work as you expect it to.

There are certain commly used vectors that opCmp() works perfectly for -
strings!

Exactly!  I see opCmp for anything (including vectors) as a sorting tool
more then anything else.  I find it very useful to be able to sort 3d
vectors.

You wouldn't be able to sort these objects, if there was an opGreater
like Patrick requests.

--
```
May 07 2004
Norbert Nemec <Norbert.Nemec gmx.de> writes:
```In the operator overloading was designed with the clear objective that
operators should only used with certain semantics and not, like in C++,
abused for all kinds of purposes.

Using "less than" and "greater than" on vectors clearly is a border case to
that. Currently these operators are meant to be used on for totally ordered
sets (like real numbers etc.).

Extending them to be used on partially ordered sets (like vectors or complex
numbers) would certainly possible. Either by introducing opLess and
opGreater, or, even easier: by allowing opCmp to return values different
from {-1,0,1} to designate "neither of the three".

Anyhow: in most cases, there is no general way to define a partial ordering.
Like for your vectors: you propose to call one vector "greater than"
another one comparing them element-wise, which is a legal partial ordering.
Someone else might rather compare their absolute value, which is a
different ordering which is just as reasonable.

For this reason, I believe it would not be a good idea to define a opCmp for
two vectors at all, but rather to define some named routine that clearly
says in which way you want to compare the two.

Patrick Horn wrote:

Currently in D there is a opCmp function returning a -1 if less, 0 if
equal or 1
if greater.  But this does not apply to classes where there the less or
greater doesn't strictly return True or False.

Consider a class for a 3-dimensional mathematical Vector.
class vector {
double i,j,k
..
}

In this class, for two vectors a and b, comparing a < b does not work
because vectors can be both greater and less (a.i<b.i but a.j>b.j)
But the problem is that opCmp can only return 1, -1 or 0, but nothing in
between. opCmp *must* return an int to work, because the compiler must
return a boolean to the expression (a>b). Therefore, this function would
be invalid:

vector opCmp (vector b) {
return vector((i>b.i)?1:((i<b.i)?-1:0), (j>b.j)?1:((j<b.j)?-1:0),
(k>b.k)?1:((k<b.k)?-1:0));
}

The solution would be to have a method such as:

vector opGreater (vector b) {
return vector(i>b.i, j>b.j, k>b.k);
}

But D should still support opCmp because it is correct in most cases.

So to support both, the compiler should parse (a>b) and call
a.opGreater(b). The Object.opGreater method would then return
(a.opCmp(b)==1).

Then, if the class overloads opGreater, the compiler will use that one
instead and ignore opCmp for that class.

```
May 07 2004
```Patrick Horn wrote:

But D should still support opCmp because it is correct in most cases.

If its so rare then your should be satisfied with using a method instead.

--
```
May 07 2004
Stewart Gordon <smjg_1998 yahoo.com> writes:
```Patrick Horn wrote:

Currently in D there is a opCmp function returning a -1 if less, 0 if equal or
1
if greater.  But this does not apply to classes where there the less or greater
doesn't strictly return True or False.

<snip>

opCmp (and hence < > <= >=) is designed to be a total ordering for such
purposes as sorting and binary searching.  Having it representing a
partial ordering would open up a whole new can of worms.

Some would argue that it would be handy to be able to invent your own
operators, but it raises such questions as precedence, associativity and
naming the implementation method.

Maybe a set of generic partial ordering operations could be invented,
with opPartCmp like opCmp but returning some magic value (perhaps
int.min) to denote neither greater, less nor equivalent.

Stewart.

--
My e-mail is valid but not my primary mailbox, aside from its being the
unfortunate victim of intensive mail-bombing at the moment.  Please keep
replies on the 'group where everyone may benefit.
```
May 07 2004
Ilya Minkov <minkov cs.tum.edu> writes:
```Patrick Horn schrieb:

In this class, for two vectors a and b, comparing a < b does not work because
vectors can be both greater and less (a.i<b.i but a.j>b.j)
But the problem is that opCmp can only return 1, -1 or 0, but nothing in
between. opCmp *must* return an int to work, because the compiler must return a
boolean to the expression (a>b). Therefore, this function would be invalid:

Harrr. Where have you studied math? To compare vectors (just as any
multi-dimensional value), you need a norm. I suggest you google after
Euclidian norm for vectors. Another valid norm would be e.g. a sum over
all vector components, because it is a special case of a norm("[...]")
|[A+B]| <= |[A] + [B]| definition.

This gets you back to linear values. Comparing anything else using
operators is counter-intuitive for the program reader/user (however
intuitive it may be for a programmer), and it is one of the goals of D
programming language to create a quality standard for software
engineering. Which includes: No operator misuse. It is a wise decision
made by Walter as he laid the groundwork of D.

-eye
```
May 10 2004