Thread overview
Operators overloading in D2
Apr 24, 2010
Dan
Apr 24, 2010
div0
Apr 26, 2010
Dan
Apr 27, 2010
bearophile
May 02, 2010
Dan
May 17, 2010
Larry Luther
April 24, 2010
Hi All,

I just downloaded D2 after a friend of mine told me about it and I was playing with it, just to get confident with the language.

In order to do that I was converting a simple geometric Vector3 class I wrote in c++. this is the (relavant for this post) D code

class Vector3
{
	float x=0.0;
	float y=0.0;
	float z=0.0;

	this() {}

	this(float X, float Y, float Z)
	{
		x=X; y=Y; z=Z;
	}

	void opOpAssign(string op:"+=")(ref Vector3 other)
	{
		x += other.x;
		y += other.y;
		z += other.z;
	}
}


I struggled immediately with operators overloading and I don't really get why they changed so drastically from D1.

for example
void opOpAssign(string op:"+=")(ref Vector3 other)
was
void opAddAssign(ref Vector3 other)

I'm not an hard core programmer and what I do is always high level or probably I worked a little to much with Python, but the old way to overload operators looks to me much more easy to understand.

So there's my questions
Why D2 changed in this way the operators overloading?
I saw the the compiler compiles both the functions, even considering this I assume it's not safe to use the old D1 way,
right?

Oh, and I've found the documentation really confusing on this metter.

Thanks,
    Dan


April 24, 2010
Dan wrote:
> Hi All,
> So there's my questions
> Why D2 changed in this way the operators overloading?
> I saw the the compiler compiles both the functions, even considering this I assume it's not safe to use the old D1 way,
> right?

Because Walter got fed up with trying to come up with the bazillon different names you need for all the operators.

Don't forget you need the array operators (eg  a[] += 5, opArrayAddAssign?!) as well as the the slicing ops (eg a[0..5] += 5, opSliceArrayAddAssign?!) which means doubling/trebling the number of old style names. Just gets sucky.

And who knows how many other operators might wind up being needed.

I didn't like it at first glance either but I've changed my mind.

- --
My enormous talent is exceeded only by my outrageous laziness.
http://www.ssTk.co.uk
April 24, 2010
On Sat, 24 Apr 2010 05:07:41 -0400, Dan <daniele.niero@gmail.com> wrote:

> So there's my questions
> Why D2 changed in this way the operators overloading?

To avoid repeating tons of boilerplate code.

For example, you can do this:

void opOpAssign(string op)(ref Vector3 other) if (op == "+=" || op == "-=")
{
   mixin("x " ~ op ~ " other.x");
   mixin("y " ~ op ~ " other.y");
   mixin("z " ~ op ~ " other.z");
}

This takes care of 2 functions with one implementation.  Other types might enjoy even more operator coverage, but vectors can't be generalized for all operators to one function.

> I saw the the compiler compiles both the functions, even considering this I assume it's not safe to use the old D1 way,
> right?

operator overloads are not special functions, they are just normal functions that the compiler calls.  You can still build opAddAssign because there is nothing inherently special about that function.  opAddAssign is a valid symbol name.

> Oh, and I've found the documentation really confusing on this metter.

Hopefully the book will clear this up.

-Steve
April 26, 2010
Thanks guys, it's more clear now.

Just another question:
are opAdd, opNeg, opAddAssign etc going to be deprecated?

The reason is very very stupid: If I use them the documentation output is much more readable :)

I know is stupid, but a good documentation is important.


Thanks again, I really hope this language will have a bright future.
     Dan
April 27, 2010
Dan:
> are opAdd, opNeg, opAddAssign etc going to be deprecated?

Yes, we can't keep two different ways, one is already complex enough.

Bye,
bearophile
April 27, 2010
On Mon, 26 Apr 2010 18:07:22 -0400, Dan <daniele.niero@gmail.com> wrote:

> Thanks guys, it's more clear now.
>
> Just another question:
> are opAdd, opNeg, opAddAssign etc going to be deprecated?
>
> The reason is very very stupid: If I use them the documentation output is much more readable :)

This is an issue brought up during the whole discussion on operator overloading.

I think what is going to be required is a change in documentation style.  So something like:

/**
  Operator overloads for +, -, ~, ...

  ...
*/

-Steve
May 02, 2010
That would be great.

Thanks again
May 17, 2010
Hi, Dan used the following method for his vector class:

  void opOpAssign (string op:"+=")(ref Vector3 other) {...}

Why the "ref"?  As I understand it, objects of class vector would already be passed as references.

  Larry


May 17, 2010
On Mon, 17 May 2010 16:38:49 -0400, Larry Luther <larry.luther@dolby.com> wrote:

> Hi, Dan used the following method for his vector class:
>
>   void opOpAssign (string op:"+=")(ref Vector3 other) {...}
>
> Why the "ref"?  As I understand it, objects of class vector
> would already be passed as references.
>
>   Larry

Yes, ref is redundant in this case.  However, you can ref a class reference, meaning you can change the passed-in class reference.

An example:

class C
{
  int x;
}

void foo(ref C xyz)
{
   xyz.x = 5
   xyz = new C;
   xyz.x = 6;
}

void bar(C xyz)
{
   xyz.x = 7;
   xyz = new C;
   xyz.x = 8;
}

void baz()
{
   C c = new C;
   c.x = 1;
   C c2 = c;
   foo(c);
   // foo changed the x member of the object c and c2 pointed to, and then
   // actually changed the object c points to.
   assert(c.x == 6 && c2.x == 5 && c !is c2);

   c2 = c;
   c.x = 1;
   bar(c);

   // bar changed the x member of the object c and c2 pointed to, and then
   // created a local C which did not affect the class reference passed in.
   assert(c.x == 7 && c2.x == 7 && c is c2);
}

-Steve