digitalmars.D.learn - Operators overloading in D2
- Dan (36/36) Apr 24 2010 Hi All,
- div0 (21/26) Apr 24 2010 -----BEGIN PGP SIGNED MESSAGE-----
- Steven Schveighoffer (18/24) Apr 24 2010 To avoid repeating tons of boilerplate code.
- Dan (7/7) Apr 26 2010 Thanks guys, it's more clear now.
- bearophile (4/5) Apr 27 2010 Yes, we can't keep two different ways, one is already complex enough.
- Steven Schveighoffer (10/15) Apr 27 2010 This is an issue brought up during the whole discussion on operator
- Dan (2/2) May 01 2010 That would be great.
- Larry Luther (5/5) May 17 2010 Hi, Dan used the following method for his vector class:
- Steven Schveighoffer (38/43) May 17 2010 Yes, ref is redundant in this case. However, you can ref a class
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
-----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
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
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
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
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
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. LarryYes, 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