August 12, 2002
It should give an ambiguity error.

"anderson" <anderson@firestar.com.au> wrote in message news:aj74ij$2v6e$1@digitaldaemon.com...
> Right, but what about?
>
> class A
> {
>     A add(B);
>     A add_r(B);
> }
>
> class B
> {
>     B add(A);
>     B add_r(A);
> }
>
> I suppose this may be illegal?
>
> A a;
> B b;
> a+b => a.add(b) & b.add(a)
> b+a => a.add_r(b) & b.add_r(a)



August 12, 2002
On Sat, 10 Aug 2002 22:08:32 -0400 "cblack01" <cblack01@cox.net> wrote:

> We have a few options.  We can put this relationship in the Vector class or we can put in the Matrix class.  It's really not entirely clear where it belongs.  But it makes more sense to me to define it outside of any class because it doesn't fit the OOP paradigm because it is a relationship between two objects.  I'm sorry to burst you OOP purist bubble. Relationships do not fit OOP.  Relationships fit the object-relational paradigm.  Dare I say the word "multimethods"?  Just my two very educated cents.

In general, you're right. But me personally, I don't care much about OOP purity or something like that... tell me, in your scheme, how does an overloaded operator, being a global function, accesses private members of classes? It is almost always needed...
August 13, 2002
It doesn't;  it deals with the public interface of the class just like everybody else.

Kinda makes me wish for friendship declarations but I'm not opposed to putting "readable" member functions that actually do the work and simple operators that just call those functions.  Gotta trust the compiler to inline stuff properly though.  Those folks seriously opposed to operator overloading can just use the "readable" versions directly.

That does bring up a point though.  How do you deal with this situation in D?

class vector
{
private float x,y,z,w;
}

class matrix
{
private vector x,y,z,w;
}

vector operator (matrix a * vector b)
{
    return vector (a.x.x * b.x + a.x.y * b.y + a.x.z * b.z + a.x.w * b.w,
                          a.y.x * b.x + a.y.y * b.y + a.y.z * b.z + a.y.w *
b.w,
                          a.z.x * b.x + a.z.y * b.y + a.z.z * b.z + a.z.w *
b.w,
                          a.w.x * b.x + a.w.y * b.y + a.w.z * b.z + a.w.w *
b.w);
}

Won't compile because obviously xyzw are all private in both classes.  So how to fix it?

class vector
{
private float x,y,z,w;
}

class matrix
{
private vector x,y,z,w;
public vector transform(vector b)
    {
        return vector (x.x * b.x + x.y * b.y + x.z * b.z + x.w * b.w,
                              y.x * b.x + y.y * b.y + y.z * b.z + y.w * b.w,
                              z.x * b.x + z.y * b.y + z.z * b.z + z.w * b.w,
                              w.x * b.x + w.y * b.y + w.z * b.z + w.w *
b.w);
    }
}

vector operator (matrix a * vector b)
{
    return a.transform(b);
}

That still doesn't work because matrix can't access members of vector.  And it won't work if you put transform into class vector either.  Have to expose some way to get at the private data, which kind of misses the point of making it private to begin with.

For this kind of thing I'd probably just make the members public anyway (and use structs instead of classes) just because I like to get at the members easily and they rarely, if ever, change.  But it's not hard to imagine some other situations like this.  Without "friend" in C++, how would you handle this situation without violating the privacy of the classes?

Sean

"Pavel Minayev" <evilone@omen.ru> wrote in message news:CFN374805064096759@news.digitalmars.com...
> On Sat, 10 Aug 2002 22:08:32 -0400 "cblack01" <cblack01@cox.net> wrote:
>
> > We have a few options.  We can put this relationship in the Vector class
or
> > we can put in the Matrix class.  It's really not entirely clear where it belongs.  But it makes more sense to me to define it outside of any
class
> > because it doesn't fit the OOP paradigm because it is a relationship
between
> > two objects.  I'm sorry to burst you OOP purist bubble. Relationships do
not
> > fit OOP.  Relationships fit the object-relational paradigm.  Dare I say
the
> > word "multimethods"?  Just my two very educated cents.
>
> In general, you're right. But me personally, I don't care much about OOP purity or something like that... tell me, in your scheme, how does an overloaded operator, being a global function, accesses private members of classes? It is almost always needed...


August 13, 2002
Probably, the simplest solution is to have user-defined opeators at global
level and let them access private member of the classes which they have as
arguments.
e.g.

class Vector
{
    private float x, y, z, w;
}

class Matrix
{
    private float x, y, z, w;
}

Vector operator(Vector a * Matrix b)
{
    /* here this function is able to access private members
    of classes Vector and Matrix */
}

I apologize if anyone has proposed this solution and it has been rejected
already.
___________________________________________________

> It doesn't;  it deals with the public interface of the class just like everybody else.
>
> Kinda makes me wish for friendship declarations but I'm not opposed to putting "readable" member functions that actually do the work and simple operators that just call those functions.  Gotta trust the compiler to inline stuff properly though.  Those folks seriously opposed to operator overloading can just use the "readable" versions directly.
>
> That does bring up a point though.  How do you deal with this situation in D?
>
> class vector
> {
> private float x,y,z,w;
> }
>
> class matrix
> {
> private vector x,y,z,w;
> }
>
> vector operator (matrix a * vector b)
> {
>     return vector (a.x.x * b.x + a.x.y * b.y + a.x.z * b.z + a.x.w * b.w,
>                           a.y.x * b.x + a.y.y * b.y + a.y.z * b.z + a.y.w
*
> b.w,
>                           a.z.x * b.x + a.z.y * b.y + a.z.z * b.z + a.z.w
*
> b.w,
>                           a.w.x * b.x + a.w.y * b.y + a.w.z * b.z + a.w.w
*
> b.w);
> }
>
> Won't compile because obviously xyzw are all private in both classes.  So how to fix it?
>
> class vector
> {
> private float x,y,z,w;
> }
>
> class matrix
> {
> private vector x,y,z,w;
> public vector transform(vector b)
>     {
>         return vector (x.x * b.x + x.y * b.y + x.z * b.z + x.w * b.w,
>                               y.x * b.x + y.y * b.y + y.z * b.z + y.w *
b.w,
>                               z.x * b.x + z.y * b.y + z.z * b.z + z.w *
b.w,
>                               w.x * b.x + w.y * b.y + w.z * b.z + w.w *
> b.w);
>     }
> }
>
> vector operator (matrix a * vector b)
> {
>     return a.transform(b);
> }
>
> That still doesn't work because matrix can't access members of vector.
And
> it won't work if you put transform into class vector either.  Have to
expose
> some way to get at the private data, which kind of misses the point of making it private to begin with.
>
> For this kind of thing I'd probably just make the members public anyway
(and
> use structs instead of classes) just because I like to get at the members easily and they rarely, if ever, change.  But it's not hard to imagine
some
> other situations like this.  Without "friend" in C++, how would you handle this situation without violating the privacy of the classes?
>
> Sean
>

> > > We have a few options.  We can put this relationship in the Vector
class
> or
> > > we can put in the Matrix class.  It's really not entirely clear where
it
> > > belongs.  But it makes more sense to me to define it outside of any
> class
> > > because it doesn't fit the OOP paradigm because it is a relationship
> between
> > > two objects.  I'm sorry to burst you OOP purist bubble. Relationships
do
> not
> > > fit OOP.  Relationships fit the object-relational paradigm.  Dare I
say
> the
> > > word "multimethods"?  Just my two very educated cents.

> > In general, you're right. But me personally, I don't care much about OOP purity or something like that... tell me, in your scheme, how does an overloaded operator, being a global function, accesses private members of classes? It is almost always needed...


August 13, 2002
Here are my votes

> I've accidentally implemented operator overloading in my port.  It was kind of incidental to other work, so I thought "what the hell" and threw it in.  But this brings up the whole issue of syntax, and I think that should be voted on to specify the syntax on my side and to influence Walter when he decides to do this topic.
>
> I'd like Apache-style voting to be used, where the voting is either -1, -0, 0, +0, or +1 for any option, which is a good bellweather of how people think about something.
>
> First off, the naming scheme:
>
> 1) "add", "mul", "div", etc.  (my vote: +1)
>
>      Vector mul (Vector b);
>      Vector div (Vector b);

+0

> 2) "op_add", "op_mul", "op_div", etc.  (my vote: +1)
>
>      Vector op_sub (Vector b);
>      Vector op_mod (Vector b);

-0

> 3) "operator +".  (my vote: -1)  My vote is because I find this syntax confusing in C++, particularly with its wide expressiveness, and I admire any syntax which doesn't require a change to tools, as the above don't.
>
>      Vector operator + (Vector b);

-0

> 4) 'operator "+"'.  (my vote: -0)  For some reason I find this less
> visually disconcerting.
>
>      Vector operator "*" (Vector b);

-0

> 5) 'operator (a - b)' or 'operator (this - b)'.  (my vote: +0)  If I had
> to put in any new syntax I would prefer it to be this one.
>
>      static Vector operator (a - b) (Vector a, Vector b);

+0

Even better the sintax someone has proposed:

// global function
Vector operator(Vector a - Vector b);

> Now, where overloaded operators are defined:
>
> 1) Operators are normal, possibly virtual methods in classes, normal
> nonvirtual methods in structs (My vote: +1).
>
>      Vector add (Vector b);

0
This vote is because the compiler won't be able to choose between a.add(b)
and b.addr(a).
The compiler will emit an ambiguity error and this will be _very_
frustrating to fix.

> 2) Overloaded operators are always static methods with both left and
> right arguments defined (My vote: 0).
>
>      static Vector add (Vector a, Vector b);

-1
Static operators are not overridable.

> 3) Overloaded operators are global functions, using both arguments (My
> vote: -1).
>
>      Vector add (Vector a, Vector b);

+1

> 4) Operator overloading shouldn't be put in (My vote: -1).

-0
(to be sincere I have rarely used it...)

> Now, reverse operator handling, where you want the right-side expression
> to handle the evaluation, such as with the form "int * Vector":
> 1) A second set of potential functions (My vote: +1).

+1

> 2) Automatic reorganization of the expression.  This makes assumptions
> about what the operators do and can't handle "1 / Vector" (My vote: -1).
>   For example, "1-A" could become "-A+1".

-1

> Now for the operations covered.  Please be temperate with your votes - operations can be added later, but they can't be removed as easily.
>
> 1) a + b, a - b, a * b, a / b, a % b, -a, +a.  (my vote: +1)

+1

> 2) a & b, a | b, a ^ b, ~a, !a.  (my vote: +1)

+1

> 3) a++, a--, --a, ++a.  (my vote: 0)

-0
This should be equivalent to a = a + 1, etc.

> 4) a = b.  (my vote: 0)

+0

> 5) a << b, a >> b, a >>> b.  (my vote: +1)

+1

> 6) a += b, a -= b, a *= b, a %= b, etc.  (my vote: -1)

-1
This should always be equivalent to a = a + b, etc.

> 7) new, delete.  (my vote: -0)

0

> 8) a || b, a && b.  (my vote: -1)

+0
Why not???

> 9) explicit a >= b, a > b, a <= b, a < b.  (my vote: -1)

+0
If we let op= to be overloaded, why not these?

> 10) a [b].  (my vote: +1)

+1

> 10a) a [b] = c.  (my vote: +0)

+1
Maybe there is a way to use settors?

> 11) a [b .. c].  (my vote: +1)

+1

> 12) &a, *a.  (my vote: -1)

-1

> 13) a.b, a.b = c.  Retrieve and assign property.  (my vote: +1)  Note
> that this won't allow just anything in b.

-1
What is this needed for?

> 13a) a . b, where b can be any type.  (my vote: -1)

-1

> 14) a ? b : c.  (my vote: -1)

-1

> 15) a === b, a !== b.  (my vote: 0)

-1

> 16) a !<> b, a <> b, a !> b, a !< b, a !<= b, a !>= b.  (my vote: 0)
> IMO this is an eq/cmp combination issue.

+0

> 17) a in b.  (my vote: +1)

+1

> 18) cast (b) a.  (my vote: -0)  I haven't had any good experiences with
> cast overloading in C++.

-1

> 19) (a, b).  (my vote: -1)

-1

Why a(b) not? This gets +0

> And miscellaneous:
>
> 1) Operator overloading should be allowed on basic types as global
> functions.  (my vote: -1)
>
>      int operator "a - b" (int a, int b);

-1
This invalidates code.

> 2) Definition of new operators is allowed.  I'll ignore this one if it
> goes positive.  (my vote: -1)
>
>      Vector operator (this dot b) (Vector b);

0

> 2a) Setting precedence of new operators is allowed.  I'll ignore this
> one if it goes positive.  (my vote: -1)
>
>      operator (a dot b) above (a >= b) below (a * b);

-1
This is too error-prone.

> I think that's about it.
>


August 13, 2002
Yes, I was considering this last week. This was when I was talking about using some type of protection mechinism (permission) like lynux does rwx rwx rwx (i think...). So you could put classes into differn't groups with differn't permissions. This of course would have other added advantages. It could be applied at the package, class, method and private method. Private, protected and public would still apply. However I don't know how this would look (it should be simple and small).

Java allows packages to access private members in that package. That's a simular but more basic approach to this idea.

The standard method in C++ was to return each member by a get/set witch was laborious and sometimes broke a class.

I think Pavel indicates that the his static version idea could have access to both (or the present???) class privates.

"Sean L. Palmer" <seanpalmer@earthlink.net> wrote in message news:ajac46$fg0$1@digitaldaemon.com...
> It doesn't;  it deals with the public interface of the class just like everybody else.
>
> Kinda makes me wish for friendship declarations but I'm not opposed to putting "readable" member functions that actually do the work and simple operators that just call those functions.  Gotta trust the compiler to inline stuff properly though.  Those folks seriously opposed to operator overloading can just use the "readable" versions directly.
>
> That does bring up a point though.  How do you deal with this situation in D?
>
> class vector
> {
> private float x,y,z,w;
> }
>
> class matrix
> {
> private vector x,y,z,w;
> }
>
> vector operator (matrix a * vector b)
> {
>     return vector (a.x.x * b.x + a.x.y * b.y + a.x.z * b.z + a.x.w * b.w,
>                           a.y.x * b.x + a.y.y * b.y + a.y.z * b.z + a.y.w
*
> b.w,
>                           a.z.x * b.x + a.z.y * b.y + a.z.z * b.z + a.z.w
*
> b.w,
>                           a.w.x * b.x + a.w.y * b.y + a.w.z * b.z + a.w.w
*
> b.w);
> }
>
> Won't compile because obviously xyzw are all private in both classes.  So how to fix it?
>
> class vector
> {
> private float x,y,z,w;
> }
>
> class matrix
> {
> private vector x,y,z,w;
> public vector transform(vector b)
>     {
>         return vector (x.x * b.x + x.y * b.y + x.z * b.z + x.w * b.w,
>                               y.x * b.x + y.y * b.y + y.z * b.z + y.w *
b.w,
>                               z.x * b.x + z.y * b.y + z.z * b.z + z.w *
b.w,
>                               w.x * b.x + w.y * b.y + w.z * b.z + w.w *
> b.w);
>     }
> }
>
> vector operator (matrix a * vector b)
> {
>     return a.transform(b);
> }
>
> That still doesn't work because matrix can't access members of vector.
And
> it won't work if you put transform into class vector either.  Have to
expose
> some way to get at the private data, which kind of misses the point of making it private to begin with.
>
> For this kind of thing I'd probably just make the members public anyway
(and
> use structs instead of classes) just because I like to get at the members easily and they rarely, if ever, change.  But it's not hard to imagine
some
> other situations like this.  Without "friend" in C++, how would you handle this situation without violating the privacy of the classes?
>
> Sean
>
> "Pavel Minayev" <evilone@omen.ru> wrote in message news:CFN374805064096759@news.digitalmars.com...
> > On Sat, 10 Aug 2002 22:08:32 -0400 "cblack01" <cblack01@cox.net> wrote:
> >
> > > We have a few options.  We can put this relationship in the Vector
class
> or
> > > we can put in the Matrix class.  It's really not entirely clear where
it
> > > belongs.  But it makes more sense to me to define it outside of any
> class
> > > because it doesn't fit the OOP paradigm because it is a relationship
> between
> > > two objects.  I'm sorry to burst you OOP purist bubble. Relationships
do
> not
> > > fit OOP.  Relationships fit the object-relational paradigm.  Dare I
say
> the
> > > word "multimethods"?  Just my two very educated cents.
> >
> > In general, you're right. But me personally, I don't care much about OOP purity or something like that... tell me, in your scheme, how does an overloaded operator, being a global function, accesses private members of classes? It is almost always needed...
>
>


August 13, 2002
"Dario" <supdar@yahoo.com> wrote in message news:ajb1or$14nq$1@digitaldaemon.com...
> Probably, the simplest solution is to have user-defined opeators at global
> level and let them access private member of the classes which they have as
> arguments.
> e.g.
>
> class Vector
> {
>     private float x, y, z, w;
> }
>
> class Matrix
> {
>     private float x, y, z, w;
> }
>
> Vector operator(Vector a * Matrix b)
> {
>     /* here this function is able to access private members
>     of classes Vector and Matrix */
> }
>
> I apologize if anyone has proposed this solution and it has been rejected already.

The major problem with that is, you open a portal for hackers and bad coding. People will missuse these operators simply for the sake of getting at private members when they should use other means. This would defeat the purpose of operators in the first place.


August 13, 2002
"Sean L. Palmer" <seanpalmer@earthlink.net> wrote in message news:ajac46$fg0$1@digitaldaemon.com...
> For this kind of thing I'd probably just make the members public anyway
(and
> use structs instead of classes) just because I like to get at the members easily and they rarely, if ever, change.  But it's not hard to imagine
some
> other situations like this.  Without "friend" in C++, how would you handle this situation without violating the privacy of the classes?

It's an interesting problem. I just don't like the C++ "friend" syntax and semantics. There's got to be a better way.


August 13, 2002
> > Probably, the simplest solution is to have user-defined opeators at
global
> > level and let them access private member of the classes which they have
as
> > arguments.
> > e.g.
> >
> > class Vector
> > {
> >     private float x, y, z, w;
> > }
> >
> > class Matrix
> > {
> >     private float x, y, z, w;
> > }
> >
> > Vector operator(Vector a * Matrix b)
> > {
> >     /* here this function is able to access private members
> >     of classes Vector and Matrix */
> > }
> >
> > I apologize if anyone has proposed this solution and it has been
rejected
> > already.

> The major problem with that is, you open a portal for hackers and bad coding. People will missuse these operators simply for the sake of getting at private members when they should use other means. This would defeat the purpose of operators in the first place.

I don't understand what you mean exactly.
There are programming language which are OO but don't support class privacy
(Python is an example).
In these languages the interface is simply a convention which programmers
aren't forced to respect. Is this agains the concept of OO programming?

Moreover, since D supports pointer arithmetic you _can_ access private
members that way. Ok, you will probably never want to, but "hacking" isn't
totally prevented as you can see.
But since D has the capability to change the member order, very few people
will do such a "hack".

Anyway shouldn't a programmer who want to access a private member simply make that member public modifying the class source code? (If the class is totally contained in an .obj file (as distributed classes usually are), you obviouly won't be able to write a new operator for that class, will you?)


August 13, 2002
On Tue, 13 Aug 2002 21:53:49 +0800 "anderson" <anderson@firestar.com.au> wrote:

> Java allows packages to access private members in that package. That's a simular but more basic approach to this idea.

This is basically the same as C++'s friend, only applied automatically.

> I think Pavel indicates that the his static version idea could have access to both (or the present???) class privates.

Well, any static function can access class privates. But only the one it resides in.

My first proposal was that operator can access private members of classes of operands and result. For example:

	Foo operator(Bar a + Baz b);

This one can access private members of classes Foo, Bar and Baz directly. Kinda auto-friend again. Unless you care much of OOP purity, it seems the simplest (both to implement and to use) approach...