www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Operators overloading in D2

reply Dan <daniele.niero gmail.com> writes:
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
Apr 24 2010
next sibling parent div0 <div0 users.sourceforge.net> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

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 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (MingW32) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iD8DBQFL0r6GT9LetA9XoXwRAuWCAJ9i+oEf1Dgk1Tn1WJ7vcjvOM0+oPwCfZNgu m+ILQWOCPfvoRQseqcd9CyA= =mmsY -----END PGP SIGNATURE-----
Apr 24 2010
prev sibling next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
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
Apr 24 2010
parent reply Dan <daniele.niero gmail.com> writes:
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
Apr 26 2010
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
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
Apr 27 2010
prev sibling parent Dan <daniel.niero gmail.com> writes:
That would be great.

Thanks again
May 01 2010
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
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
Apr 27 2010
prev sibling parent reply "Larry Luther" <larry.luther dolby.com> writes:
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
parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
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
May 17 2010