August 01, 2002
"Jonathan Andrew" <jon@ece.arizona.edu> wrote in message news:3D4862F1.3070709@ece.arizona.edu...
> anderson wrote:
> > "Pavel Minayev" <evilone@omen.ru> wrote in message
> > news:CFN374676619595486@news.digitalmars.com...
> > On Tue, 30 Jul 2002 11:00:57 +0200 "Sandor Hojtsy" <hojtsy@index.hu>
wrote:
> >
> >
> >>class Vector
> >>{
> >>...
> >>static operator* (Vector a, Vector b) { ... }
> >>static operator* (Vector a, int b) { ... }
> >>}
> >
> >
> >>Short and clear.
> >
> >
> > I think * would be confused with pointers.
> >
> >
> >>>How would you rewrite 1-A ?
> >>
> >
> > Juan offered a better solution I think because you get proper access to
the
> > object properties and it's less special-case.
> >
> >
>
> You would have to have different 'keywords' for each symbol, i.e, for vectors you might want to overload * for cross product and constant multiples, but have . for dot product also, which one would mul be? I suppose you could have a dot keyword also, but I like the idea of being able to explicitly specify which symbol to use.
>
> Maybe something like
> class Vector
> {
>       static operator(*) cross(VectorA, VectorB);
>       static operator(*) mul(VectorA, int);
>       static operator(.) dot(VectorA, VectorB);
>       .... etc.
> }
>
> This way, those who don't like operator overloading could
> still call the functions by name, i.e. cross(), dot() etc.
> and you could specify which symbol to use also.
> Just an idea,
>   -Jon

No, I agree with you. I was thinking (to stop it looking pointerish) ...

 class Vector
 {
       operator<*>(VectorA, VectorB);
       operator<->(VectorA, int);
       operator<.>(VectorA, VectorB);
       .... etc.
 }
Or another symbol because () makes it look like a weird function (but is
better then without).

because it's having to remember the name for each symbol simply means more learning. The more things you have in the language the more you need to remember. However if the user could specify any name they wished... Anyhow in your example how would the complier determine the differce between a cross and a mul? I think that would be a bug.

Also I think that it shouldn't be static. I like Juan's approach here better.

My approch is closest to Juan (uses differn't syntax).

 class VectorA
 {
       leftOperator<*>(VectorB);
       leftOperator<->(int);
       leftOperator<.>(VectorB);
       rightOperator<.>(VectorB);
 }

or even simpler

 class VectorA
 {
       left<*>(VectorB);
       left<->(int);
       left<.>(VectorB);
       right<.>(VectorB);
 }

and users who what to specify...

 class VectorA
 {
       left<*> mul(VectorB);
       left<-> whatever(int);
       left<.> dot(VectorB);
       right<.> dot(VectorB);
 }

This way you don't have to special case access to class member properties. If you give programs to much power, some are likly to abuse it.


August 01, 2002
> 
> No, I agree with you. I was thinking (to stop it looking pointerish) ...
> 
>  class Vector
>  {
>        operator<*>(VectorA, VectorB);
>        operator<->(VectorA, int);
>        operator<.>(VectorA, VectorB);
>        .... etc.
>  }
> Or another symbol because () makes it look like a weird function (but is
> better then without).

True, <> would be a good choice.

> because it's having to remember the name for each symbol simply means more
> learning. The more things you have in the language the more you need to
> remember. However if the user could specify any name they wished... Anyhow
> in your example how would the complier determine the differce between a
> cross and a mul? I think that would be a bug.

It would determine it from the operators, if you had cross and mul
that both accepted two vectors, it should err.
In my case mul was a constant multiplier.

> Also I think that it shouldn't be static. I like Juan's approach here
> better.

Having static operators available (though not necessary) would be
convenient for a lot of cases, like a math class.

> My approch is closest to Juan (uses differn't syntax).
> 
>  class VectorA
>  {
>        leftOperator<*>(VectorB);
>        leftOperator<->(int);
>        leftOperator<.>(VectorB);
>        rightOperator<.>(VectorB);
>  }
> 
> or even simpler
> 
>  class VectorA
>  {
>        left<*>(VectorB);
>        left<->(int);
>        left<.>(VectorB);
>        right<.>(VectorB);
>  }
> 
> and users who what to specify...
> 
>  class VectorA
>  {
>        left<*> mul(VectorB);
>        left<-> whatever(int);
>        left<.> dot(VectorB);
>        right<.> dot(VectorB);
>  }
> 
> This way you don't have to special case access to class member properties.
> If you give programs to much power, some are likly to abuse it.
> 
> 

Hmm, I dunno, that is more concise, but it seems a little harder to
understand.

August 01, 2002
"Jonathan Andrew" <jon@ece.arizona.edu> wrote in message news:3D48D3BE.404@ece.arizona.edu...
>
> >
> > No, I agree with you. I was thinking (to stop it looking pointerish) ...
> >
> >  class Vector
> >  {
> >        operator<*>(VectorA, VectorB);
> >        operator<->(VectorA, int);
> >        operator<.>(VectorA, VectorB);
> >        .... etc.
> >  }
> > Or another symbol because () makes it look like a weird function (but is
> > better then without).
>
> True, <> would be a good choice.
>
> > because it's having to remember the name for each symbol simply means
more
> > learning. The more things you have in the language the more you need to remember. However if the user could specify any name they wished...
Anyhow
> > in your example how would the complier determine the differce between a cross and a mul? I think that would be a bug.
>
> It would determine it from the operators, if you had cross and mul
> that both accepted two vectors, it should err.
> In my case mul was a constant multiplier.
>
> > Also I think that it shouldn't be static. I like Juan's approach here better.
>
> Having static operators available (though not necessary) would be convenient for a lot of cases, like a math class.
>
> > My approch is closest to Juan (uses differn't syntax).
> >
> >  class VectorA
> >  {
> >        leftOperator<*>(VectorB);
> >        leftOperator<->(int);
> >        leftOperator<.>(VectorB);
> >        rightOperator<.>(VectorB);
> >  }
> >
> > or even simpler
> >
> >  class VectorA
> >  {
> >        left<*>(VectorB);
> >        left<->(int);
> >        left<.>(VectorB);
> >        right<.>(VectorB);
> >  }
> >
> > and users who what to specify...
> >
> >  class VectorA
> >  {
> >        left<*> mul(VectorB);
> >        left<-> whatever(int);
> >        left<.> dot(VectorB);
> >        right<.> dot(VectorB);
> >  }
> >
> > This way you don't have to special case access to class member
properties.
> > If you give programs to much power, some are likly to abuse it.
> >
> >
>
> Hmm, I dunno, that is more concise, but it seems a little harder to understand.
>

I really don't care that much. Whatever is writeable, readable, doesn't cause specail cases, easy to learn and effecient.

Acually when I first used C++ (a few years ago now) I tried to make an
operator like this...
class VectorA
{
      * (VectorB);
      - (int);
      . (VectorB);
}

...but of course there are problems with that such as the right/left rules.


August 01, 2002
Jonathan Andrew wrote:

> 
> Maybe something like
> class Vector
> {
>       static operator(*) cross(VectorA, VectorB);
>       static operator(*) mul(VectorA, int);
>       static operator(.) dot(VectorA, VectorB);
>       .... etc.
> }
> 
> This way, those who don't like operator overloading could
> still call the functions by name, i.e. cross(), dot() etc.
> and you could specify which symbol to use also.
> Just an idea,
>   -Jon

I like the idea - especially as it is similar to the method I use in my language (oomic) .. however in the latter case the syntax is different so you would get:

        function subtract Vector as ( a - b )
        ;;      a       Vector
        ,       b       Vector
        { ... }
        function negate Vector as ( - a )
        ;;      a       Vector
        { ... }

The main advantage here is that the equation parser can be used to parse
the operator overloading specifier.
Here of course there is no need to specify left / right / binary association
(though post fix operators are not allowed in the current version).
Maybe this idea could be adapted for D?

C 2002/8/1
August 01, 2002
Hi,

"Jonathan Andrew" <jon@ece.arizona.edu> wrote in message news:3D48D3BE.404@ece.arizona.edu...
> >        operator<.>(VectorA, VectorB);
> >        .... etc.
> True, <> would be a good choice.

Not really, considering the operators "<", ">", "<<", ">>", etc. "operator<<>" would be recognized by the lexer as the three tokens "operator", "<<", and ">", thereby introducing the need for extra spacing as in "operator< < >" ("<>" is a token recognized by the lexer too). Its the same problem as with templates in C++ - let us learn from it.

Regards,
Martin M. Pedersen



August 01, 2002
"anderson" <anderson@firestar.com.au> wrote in news:aia87q$2m8d$1 @digitaldaemon.com:

> No, I agree with you. I was thinking (to stop it looking pointerish) ...
> 
>  class Vector
>  {
>        operator<*>(VectorA, VectorB);
>        operator<->(VectorA, int);
>        operator<.>(VectorA, VectorB);
>        .... etc.
>  }
> Or another symbol because () makes it look like a weird function (but is
> better then without).


Why not use the keyword and type already available in language :

Class Vector
{
    	void add (int A) {}      	// V + 1
    	int add () {}     	    	// 1 + A
}
August 01, 2002
"Martin M. Pedersen" wrote:

> Hi,
>
> "Jonathan Andrew" <jon@ece.arizona.edu> wrote in message news:3D48D3BE.404@ece.arizona.edu...
> > >        operator<.>(VectorA, VectorB);
> > >        .... etc.
> > True, <> would be a good choice.
>
> Not really, considering the operators "<", ">", "<<", ">>", etc. "operator<<>" would be recognized by the lexer as the three tokens "operator", "<<", and ">", thereby introducing the need for extra spacing as in "operator< < >" ("<>" is a token recognized by the lexer too). Its the same problem as with templates in C++ - let us learn from it.
>
> Regards,
> Martin M. Pedersen

Hmm, fair enough, I guess we need to invent a keyboard with some new brackets =)

If anything though, I think this whole thread has shown me that built-in vector support in the language would be greatly appreciated!

August 01, 2002
Juarez Rudsatz wrote:

> "anderson" <anderson@firestar.com.au> wrote in news:aia87q$2m8d$1 @digitaldaemon.com:
>
> > No, I agree with you. I was thinking (to stop it looking pointerish) ...
> >
> >  class Vector
> >  {
> >        operator<*>(VectorA, VectorB);
> >        operator<->(VectorA, int);
> >        operator<.>(VectorA, VectorB);
> >        .... etc.
> >  }
> > Or another symbol because () makes it look like a weird function (but is
> > better then without).
>
> Why not use the keyword and type already available in language :
>
> Class Vector
> {
>         void add (int A) {}             // V + 1
>         int add () {}                   // 1 + A
> }

This keeps you from being able to define new symbols to use, and
sometimes there are cases where it would be nice to use symbols
that don't necessarily represent adding, so forth.
For example, if you had some kind of class for a signal function,
and you wanted * to represent convolution, you wouldn't want to
use a function called mul() to represent that operation, even though
it uses the same symbol. (on a keyboard at least)


August 01, 2002
On Thu, 1 Aug 2002 17:29:48 +0100 "Martin M. Pedersen" <mmp@www.moeller-pedersen.dk> wrote:

> Not really, considering the operators "<", ">", "<<", ">>", etc. "operator<<>" would be recognized by the lexer as the three tokens "operator", "<<", and ">", thereby introducing the need for extra spacing as in "operator< < >" ("<>" is a token recognized by the lexer too). Its the same problem as with templates in C++ - let us learn from it.

I think round braces are the best choice. When grouped properly, they look just alright:

	vector operator(+) (vector a, vector b)
	{
		...
	}
August 01, 2002
"Pavel Minayev" <evilone@omen.ru> wrote in message news:CFN374624470316435@news.digitalmars.com...
> On Wed, 24 Jul 2002 18:09:33 -0700 "Walter" <walter@digitalmars.com>
wrote:
>
> > A better approach would be to simply disallow overloading the global operators, and say "no" to overloading the syntax:
> >
> >     1 + A;
>
> On other hand, it might be even better to disallow _member_ operators, and require all operators overloading to be global. Then, you don't have to care about things like virtual operators, overloading etc - it's all naturally done by pointer conversions.

Of course, you're right, but unfortunately I screwed up and allowed the cmp operator to be a member <g>.