March 24, 2004
"Manfred Nowak" <svv1999@hotmail.com> wrote in message news:c3sl7u$bjt$1@digitaldaemon.com...
> Ilya Minkov wrote:
>
> [...]
> > The purpose of _r overloads was to be able to add new overloads in newly written classes to the already exisiting infrastructure.
> [...]
>
> Do you have a reference for this? I ask, because I do not believe, that classes in any infrastructure are not allowed to have other types than classes/structs on the left side of a non commutative operator.

Not true, example from spec:

class B { int opDiv_r(int i); }
	B b;
	1 / b;	// equivalent to b.opDiv_r(1)

> [...]
> > but it doesn't match) a reversed overload has to be searched in B.
>
> I do not believe that it is possible to code such overloads in the general case you established as an example. How can you assure, that it would suffice to have access to the public parts of class/struct A?
>
>
> [...]
> > you could just as well remove all _r overloads!
>
> A stated above `B.opfunc_r(int)' may still make sense.
>
> So long!
>
>


March 24, 2004
"Manfred Nowak" <svv1999@hotmail.com> wrote in message news:c3sl87$c96$2@digitaldaemon.com...
> Ivan Senji wrote:
>
> [...]
> > A.opShl(B) should be same as B.opShl_r(A).
> [...]
>
> Should be. But this cannot be checked in the general case. Therefore the coexistence of both must be forbidden.

My example doesn't involve coexistence of both operators! I
I only have B.opShl_r(A) and it is not called because A.opShl(int) and
A.opShl(char[]) exist.

> I am unsure whether the compiler should check that for all possible competing classes/structs or it may suffice to check it only, when such classes/structs actually compete.
>
> [...]
> > see << and >> as stream operators
> [...]
>
> Which is a strange and counter intuitive speciality made for {101}'s, not suitable for {500}'s.
>
> So long!


March 24, 2004
<snip>
>I (and probably a lot of other people coming from C++) see << and >> as stream operators before left-shifting.
</snip>

And it seems that's _why_ Walter doesn't want operators to be (ab)used for things like that. << is leftshift, >> is rightshift, and should _never_ have been used as stream operators in the first place.

And even as stream operators; A<<B is not the same as B<<A !!


March 24, 2004
Ivan Senji wrote:

[...]
> Not true, example from spec:
> 
> class B { int opDiv_r(int i); }
> 	B b;
> 	1 / b;	// equivalent to b.opDiv_r(1)
[...]

Thanks for this confirmation from the spec for my suspicion.

So long!


March 24, 2004
Ivan Senji wrote:

[...]
> My example doesn't involve coexistence of both operators! I
> I only have B.opShl_r(A) and it is not called because A.opShl(int) and
> A.opShl(char[]) exist.
[...]

I noticed that. And because your classes do not compete for the `<<' operator, there is good reason to allow B's `opShl_r' to be called.

There is one more reason that especially your example should be allowed: your `opShl_r' returns the type of the left operand, which is the only requirement for the `<<' operator, which can be extracted from the spec. And as far as I can deduce from opover.c this requirement is not checked for by dmd.

However, are you aware that your approach to mimic C++'s stream operator in D is illegal according to the spec? That is because the evaluation order for the operands of consecutive `<<'s is not defined. In the current version of dmd it may work, but in the next version or in another compiler may result in a syntax error.

If you want such evaluated from left to right, you have to put it fully in brackets from left to right, which would totally obfuscate your purpose.

So long!

March 24, 2004
"Manfred Nowak" <svv1999@hotmail.com> wrote in message news:c3sqjj$tq9$1@digitaldaemon.com...
> Ivan Senji wrote:
>
> [...]
> > My example doesn't involve coexistence of both operators! I
> > I only have B.opShl_r(A) and it is not called because A.opShl(int) and
> > A.opShl(char[]) exist.
> [...]
>
> I noticed that. And because your classes do not compete for the `<<' operator, there is good reason to allow B's `opShl_r' to be called.
>
> There is one more reason that especially your example should be allowed: your `opShl_r' returns the type of the left operand, which is the only requirement for the `<<' operator, which can be extracted from the spec. And as far as I can deduce from opover.c this requirement is not checked for by dmd.
>
> However, are you aware that your approach to mimic C++'s stream operator in D is illegal according to the spec? That is because the evaluation order for the operands of consecutive `<<'s is not defined. In the current version of dmd it may work, but in the next version or in another compiler may result in a syntax error.

OOPS! I didn't realize that(Thanks). But it isn't my intention to mimic
C++'s streams, i am only experimenting :)
I have another example (for this one no one can say it is abuse of
operators):

Lets say someone wrote a library that has a Matrix class.
And I write a Vector class because i need it and i would like to use it
together with Matrix

Matrix class has "Matrix.opMul(Matrix)"
and i wan't my Vector class to have
Vector opMul(Matrix m)

now i can use it like this:

Matrix m1 = v1 * m2;
but i can't use it like this:

Matrix m1 = m2 * v1;

Even if there existed opMul_r operator (i don't know why there isn't one)
this still wouldn't work becouse of the
Matrix.opMul(Matrix)!

I like most every other feature of D very much (especially templates) but i
just think
there is something wrong in D's operator overloading!

I don't think there is any solution to the problems like the one with Matrix
 and Vector. :( ?


> If you want such evaluated from left to right, you have to put it fully in brackets from left to right, which would totally obfuscate your purpose.
>
> So long!
>


March 24, 2004
"Juan c" <Juan_member@pathlink.com> wrote in message news:c3sf1l$ib$1@digitaldaemon.com...
> Huh?! But A<<B is not the same as B<<A. I think you are trying to abuse
the
> operator, and Walter doesn't like that. The << operator should _only_ be
used to
> perform a left-shifting operation, which is not commutative.

I was wondering... what is the definition of abuse of operator? This code can be written in D, is this abuse?

class ABC
{
    static int opMul(char[] x){return 1;}
    static ABC opDiv(char[] x){return new ABC();}
}

ABC * "hello";
ABC abc = ABC / "hello again";

Is this code abuse? I think that there can't even be a definition of
operator abuse because todays
language features allow us to write things like the above. In the code above
* and / obviously dont
have the meaning of multiplication and division, but i like that we have the
freedom to write
something like that. Maybe the above code could have meaning to someone in
some situation.

It doesn't make sence that the language lets us write things like the above,
but makes it impossible
to use operators in some very common situations!

> In article <c3sbqj$2s6n$2@digitaldaemon.com>, Ilya Minkov says...
> >
> >Ivan Senji schrieb:
> >
> >> I dont't agree! A contains functions opShl(int) and opShl(char[]) but
it
> >> doesnt contain
> >> opShl(B) so it should still check if B contains opShl(A).
> >
> >I don't "agree" either, but so is the current spec. I checked it.
> >
> >-eye
>
>


March 24, 2004
Juan C schrieb:

> And it seems that's _why_ Walter doesn't want operators to be (ab)used for
> things like that. << is leftshift, >> is rightshift, and should _never_ have
> been used as stream operators in the first place.

Perhaps. This is not the subject now.

> And even as stream operators; A<<B is not the same as B<<A !!

Like, you're not getting it. We are only talking of A<<B - but insert something more sane in the place of <<, it can be % or ~ or whatever. This case can be resolved as A.Op(B) or B.Op_r(A). Notice that _r? It's to be able to expand the operator overloads without changing established class libraries. Now, the compiler refuses to consider the B.Op_r(A) resolution, because A.Op() is defined for some other type than B.

This nonsensical situatition conforms to the specification. So i'd say the spec should be changed. It's not simply nonsensical, it's outright dangerous. Imagine A doesn't define .Op and there is a ton arbitrary code which defines .Op_r(A). Then the author of A decides to add a few .Op overloads to it. This breaks all other code which relies on the definitions of .Op_r(A), even if there is *no* *direct* *conflict*, that is no definition of C.Op_r(A) corresponds to A.Op(C) simply because the author of A is not aware of C, but C is aware of and requieres/uses A.

-eye
March 24, 2004
<snip>
>I was wondering... what is the definition of abuse of operator?
</snip>

It can't be defined, because not everyone would agree with any particular definition, or even whether or not such a concept is valid.

I could say, "any implementation of an operator that differs substantially from its normal mathematical meaning". But that can be viewed as vague and maybe only half the people in this group would agree that that's abuse anyway. Many, like you perhaps, would argue that any operator can be used for any purpose.

<analogy>
Even though my SUV _allows_ me to drive anywhere, I am still obliged to follow
the roads, so that other drivers can _reasonably predict_ what I'm likely to do.
</analogy>


March 24, 2004
Ivan Senji wrote:

>"Manfred Nowak" <svv1999@hotmail.com> wrote in message
>news:c3sqjj$tq9$1@digitaldaemon.com...
>  
>
>>Ivan Senji wrote:
>>
>>[...]
>>    
>>
>>>My example doesn't involve coexistence of both operators! I
>>>I only have B.opShl_r(A) and it is not called because A.opShl(int) and
>>>A.opShl(char[]) exist.
>>>      
>>>
>>[...]
>>
>>I noticed that. And because your classes do not compete for the `<<'
>>operator, there is good reason to allow B's `opShl_r' to be called.
>>
>>There is one more reason that especially your example should be allowed:
>>your `opShl_r' returns the type of the left operand, which is the only
>>requirement for the `<<' operator, which can be extracted from the spec.
>>And as far as I can deduce from opover.c this requirement is not checked
>>for by dmd.
>>
>>However, are you aware that your approach to mimic C++'s stream operator
>>in D is illegal according to the spec? That is because the evaluation
>>order for the operands of consecutive `<<'s is not defined. In the current
>>version of dmd it may work, but in the next version or in another compiler
>>may result in a syntax error.
>>    
>>
>
>OOPS! I didn't realize that(Thanks). But it isn't my intention to mimic
>C++'s streams, i am only experimenting :)
>I have another example (for this one no one can say it is abuse of
>operators):
>
>Lets say someone wrote a library that has a Matrix class.
>And I write a Vector class because i need it and i would like to use it
>together with Matrix
>
>Matrix class has "Matrix.opMul(Matrix)"
>and i wan't my Vector class to have
>Vector opMul(Matrix m)
>
>now i can use it like this:
>
>Matrix m1 = v1 * m2;
>but i can't use it like this:
>
>Matrix m1 = m2 * v1;
>
>Even if there existed opMul_r operator (i don't know why there isn't one)
>this still wouldn't work becouse of the
>Matrix.opMul(Matrix)!
>  
>
In this case the operation is comunitative, so m2 * v1 and v1 * m2 are the same thing.  Check out dig for a good matrix class.

-- 
-Anderson: http://badmama.com.au/~anderson/