Operators overloading in D2
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
Re: Operators overloading in D2
-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-
Re: Newsgroups, off-topic
Steven Schveighoffer wrote: I did a little review of the code, I concur that the code is pretty identical, and the D version does not really do any extra allocation. I found one place where you were using pow(x, 2) to square something in the D version but doing it with simple multiplication in the C++ version, but that didn't account for any slowdowns when fixed. I also saw some places where you write 0 to arrays several times, but removing those didn't help either. Not several times superfluously? I think I would be embarrassed if that were true :-P I can only attribute the difference to g++'s more mature optimization/inlining techniques. I can see why you are interested in having gdc working to try and compare the two :) ldc already speeds things up somewhat (its inlining is better), but still leaves a fairly sizeable gap. There seem to be some fairly sizeable performance differences between gcc and llvm: http://www.phoronix.com/scan.php?page=articleitem=apple_llvm_gccnum=1 ... which if I recall correctly was the motivation for the current gdc team to start working on it again. In spite of all this, I still remain convinced that there is nothing inherently bad about these results, D compilers can and probably will get better at optimizing code. That it doesn't beat a compiler which has been in production/mainstream for many more years probably shouldn't be surprising to any of us, even though we want D compilers to perform the best. Completely agree here. I was concerned based on early experience that I was doing 'un-D-ish' things that were screwing performance, but now I'm fairly confident that I can write OK D code. From now on it will be all pleasure as the compilers speed things up ... :-) Thanks and best wishes, -- Joe
Re: Newsgroups, off-topic
On Sat, 24 Apr 2010 05:32:25 -0400, Joseph Wakeling joseph.wakel...@webdrake.net wrote: Steven Schveighoffer wrote: I did a little review of the code, I concur that the code is pretty identical, and the D version does not really do any extra allocation. I found one place where you were using pow(x, 2) to square something in the D version but doing it with simple multiplication in the C++ version, but that didn't account for any slowdowns when fixed. I also saw some places where you write 0 to arrays several times, but removing those didn't help either. Not several times superfluously? I think I would be embarrassed if that were true :-P Hm... I hate to embarrass you :) I found it while manually inlining some functions (to try and see if that helps speed it up). So it wasn't obvious until I saw the two lines together. In Yzlm.objectReputationUpdate, you zero out reputationObject array, then call super.opCall, which also zeros out reputationObject. It's understandable that this got introduced in the D version, you are doing something quite different than in the C++ version, swapping with another array and you were just being thorough. I wouldn't be too embarrassed, and I note that it doesn't affect the runtime significantly anyways. In spite of all this, I still remain convinced that there is nothing inherently bad about these results, D compilers can and probably will get better at optimizing code. That it doesn't beat a compiler which has been in production/mainstream for many more years probably shouldn't be surprising to any of us, even though we want D compilers to perform the best. Completely agree here. I was concerned based on early experience that I was doing 'un-D-ish' things that were screwing performance, but now I'm fairly confident that I can write OK D code. From now on it will be all pleasure as the compilers speed things up ... :-) Thanks and best wishes, Good luck to you too! -Steve
Re: Operators overloading in D2
On Sat, 24 Apr 2010 05:07:41 -0400, Dan daniele.ni...@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
Arrays of many different (sub)classes
Hello all, Occasionally in C++ I find it useful to build an array which contains classes of multiple different types all using the same interface -- by constructing an array of pointers to some common base class, e.g. class BaseClass { // blah, blah ... }; class A : BaseClass { // ... blah ... }; class C : BaseClass { // ... blah ... }; int main() { vectorBaseClass * vec; vec.push_back(new A()); vec.push_back(new C()); // etc. etc. } (This code might be wrong; I'm just typing it to give the idea. And in practice, I usually do not use 'new' statements but pass pointers to already-existing objects...:-) Anyway, the point is that at the end of the day I have an array of different objects with a common interface. What's the appropriate way to achieve the same effect in D? Thanks best wishes, -- Joe
Re: Arrays of many different (sub)classes
On 24/04/10 20:06, Joseph Wakeling wrote: Hello all, Occasionally in C++ I find it useful to build an array which contains classes of multiple different types all using the same interface -- by constructing an array of pointers to some common base class, e.g. class BaseClass { // blah, blah ... }; class A : BaseClass { // ... blah ... }; class C : BaseClass { // ... blah ... }; int main() { vectorBaseClass * vec; vec.push_back(new A()); vec.push_back(new C()); // etc. etc. } (This code might be wrong; I'm just typing it to give the idea. And in practice, I usually do not use 'new' statements but pass pointers to already-existing objects...:-) Anyway, the point is that at the end of the day I have an array of different objects with a common interface. What's the appropriate way to achieve the same effect in D? Thanks best wishes, -- Joe This should do what you want: class BaseClass { // blah, blah ... } class A : BaseClass { // ... blah ... } class C : BaseClass { // ... blah ... } int main() { BaseClass[] vec; vec ~= new A; vec ~= new C; // etc. etc. }