www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Re: Redundancies often reveal bugs

reply bearophile <bearophileHUGS lycos.com> writes:
Thank you for all the answers.

Daniel Gibson:	

 Well, maybe "this(int this.x, int this.y, int a)" would be better.

This reduces useless code in the constructor and keep the code more DRY, looks able to avoid part of the problems I was talking about (but not all of them). So this struct: // Code #1 struct Something { int x, y, aa; this(int x_, int y_, int a_) { this.x = x_; this.y = y_; this.aa = a_ * a_ + x_; } void update(int x_, int b) { this.x = x_; this.aa += b; } } May be written (it's just syntax sugar): // Code #2 struct Something { int x, y, aa; this(this.x, this.y, int a_) { this.aa = a_ * a_ + x; } void update(this.x) { this.aa += b; } } In some situations you need constructor arguments to be of type different from instance attributes. In such situations you may use the normal old syntax. Or instance argument types may be optional, so this code: // Code #3 class Foo {} class Bar : Foo {} class Something { Foo c; this(Bar c_) { this.c = c_; } } void main() { auto s = new Something(new Bar); } May be written: // Code #4 class Foo {} class Bar : Foo {} class Something { Foo c; this(Bar this.c) {} } void main() { auto s = new Something(new Bar); } That syntax idea is nice to avoid some code duplication, and I'd like to have it if it has no bad side effects (beside making the language a bit more complex), but it can't avoid bugs like the following inc(), so I think it's not enough to solve the problems I was talking about: // Code #5 class Foo { int x; void inc(int x) { x += x; } } void main() {} Despite Python is seen by some people as a scripting language unfit for larger programs, it contains many design decisions able to avoid several kinds of bugs (that are often enough present in D programs too). Regarding the bugs discussed in this post, Python is able to avoid some of them because inside methods all instance attributes must be prefixed by a name typically like "self." (and class instance attributes, that are similar to static class attributes in D, must be prefixed by the class name). So some of the troubles in D code I am talking about may be avoided requiring the "this." prefix where the code may be ambiguous for the programmer (I am not talking about code ambiguous for the compiler). This can't avoid troubles like in Code #5. The only good way I see to avoid troubles like in Code #5 is to forbid the method arguments that have the same name as class/struct/union attributes (this is what bug 3878 is about). For the problems we are talking in this thread probably more than one solution at the same time is needed. The method "this" arguments seem a nice idea to improve the DRY-ness of the code and avoid some bugs, the obligatory usage of the "this." prefix when the code is ambiguous for the programmer helps avoid other bugs, and maybe a warning for x=x; lines of code is useful, and a warning for unused variables and unused last assigned values too are useful to avoid other bugs. Bye, bearophile
Oct 01 2010
next sibling parent "Simen kjaeraas" <simen.kjaras gmail.com> writes:
bearophile <bearophileHUGS lycos.com> wrote:

 but it can't avoid bugs like the following inc(), so I think it's not  
 enough to solve the problems I was talking about:


 // Code #5
 class Foo {
     int x;
     void inc(int x) { x += x; }
 }
 void main() {}

Oh, but it can (sort of). By allowing this syntax, there is *very* little reason to allow for shadowing of members by parameters or local variables, and those may thus more readily be disallowed. -- Simen
Oct 01 2010
prev sibling parent bearophile <bearophileHUGS lycos.com> writes:
 // Code #2
 struct Something {
     int x, y, aa;
     this(this.x, this.y, int a_) {
         this.aa = a_ * a_ + x;
     }
     void update(this.x) {
         this.aa += b;
     }
 }

Sorry, that's wrong. The correct part: void update(this.x, int b) { this.aa += b; } Bye, bearophile
Oct 01 2010