digitalmars.D - struct inheritance, L-value return
- cschueler (80/80) Jun 12 2006 A little report on recent tamperings with D.
- mclysenk mtu.edu (19/28) Jun 12 2006 I've had to deal with my share of vector/matrix classes. I personally h...
- Oskar Linde (24/102) Jun 13 2006 Try adding an anonymous struct to the template:
- Chris Nicholson-Sauls (4/23) Jun 13 2006 Write MyArray.opIndex to return a pointer and it will work. I do still ...
- Oskar Linde (4/27) Jun 13 2006 That will work in this case, but will break the rvalue case instead:
- Regan Heath (5/30) Jun 13 2006 point pt = *arr[6];
A little report on recent tamperings with D. I often deal with primitive types which are "vector spaces". Examples * 3D-vectors * colors * quaternions * matrices. While these are distinct types with distinct operations, they all have in common that they can add and subtract members of their kin, and multiply them with a scalar. They also have a zero (neutral) element. This is what the term vector space is mathematically about. In the C++ world, I was so annoyed that I had to type the same boilerplate stuff over and over again for each of these types that I invented my "vector space" template system. With this system it is possibly to declare a vector space type with minimum effort and have all the basic operations ready to go. It seems I cannot port this system to D with the current state of D. The short story is I need either - struct inheritance or - anonymous unions outside an aggregate in a mixin I would prefer struct inheritance: struct field { union { ... }; union { ... }; union { ... }; }; struct vectorspace : field { // have anonymous unions of "field" injected into this scope } but I since there is no struct inheritance, I tried with mixins template field { union { ... }; union { ... }; union { ... }; }; struct vectorspace { mixin field; } But you cannot have anonymous unions outside a struct :/( So I'm struck at this point. Moreover, the mixin approach is not feasible because then you cannot make field a template parameter. template( field ) { struct vectorspace only seem to work when field is a type, not a mixin. I would like to weigh in for struct inheritance, since it seems a trivial thing to allow. C programmers have often done this by declaring a variable of the base type as the first member of the struct. So I was a little surprised that D has no inheritance for plain data structs. There is more missing in D that prevents me to port the system fully: - explicit return by reference (return an L-value) - struct constructors These are not showblockers, but missing them is ugly! I see from the archives that struct constructors have been discussed already, so count me as another vote for struct constructors here. The explicit L-value return however I think is an important concept that is missing with subtle implications. Without it, user defined types can never be made transparent to builtin types. Consider: int a; (+a) = 3; The unary plus operator returns an L-value, so the assignment can take place. In C++, you can define the unary + operator to behave the same for your type, by defining both R-value and L-value operator: // R-value unary + const mytype &operator +( const mytype &object ) { return object; } // L-value unary + mytype &operator +( mytype &object ) { return object; } In D, you can only do the R-value version.
Jun 12 2006
In article <e6l2mu$1242$1 digitaldaemon.com>, cschueler says...I would like to weigh in for struct inheritance, since it seems a trivial thing to allow. C programmers have often done this by declaring a variable of the base type as the first member of the struct. So I was a little surprised that D has no inheritance for plain data structs. There is more missing in D that prevents me to port the system fully: - explicit return by reference (return an L-value) - struct constructorsI've had to deal with my share of vector/matrix classes. I personally hate writing the damn things, since they are so tedious. I'd hoped array ops or something like that would provide a native solution, but I don't think it's gonna happen any time soon. Anyway, struct inheritance is a tricky business. I do not think that structs should be able to inherit functions, since that makes them no different than a class, just like they are in C++. A struct should be treated specially, it should not have a virtual function table or any extra run time information like a class does. As for struct constructors, the common tactic is to use opCall, but I agree that some solution involving the 'this' keyword would be more consistent. The current solution is workable, though a bit obscure. I'm a bit uneasy about that whole l-value thing. As a design decision, it seems to violate the design principal of encapsulation. If you absolutely have to write to an object via its return value, you could try returning a pointer. The library I currently use is based on SSE, though the optimization is still incomplete. You can grab it from http://assertfalse.com -Mik
Jun 12 2006
cschueler skrev:The short story is I need either - struct inheritance or - anonymous unions outside an aggregate in a mixin I would prefer struct inheritance: struct field { union { ... }; union { ... }; union { ... }; }; struct vectorspace : field { // have anonymous unions of "field" injected into this scope } but I since there is no struct inheritance, I tried with mixins template field { union { ... }; union { ... }; union { ... }; }; struct vectorspace { mixin field; } But you cannot have anonymous unions outside a struct :/( So I'm struck at this point.Try adding an anonymous struct to the template: template field() { struct { union {...} union {...} union {...} } }Moreover, the mixin approach is not feasible because then you cannot make field a template parameter. template( field ) { struct vectorspace only seem to work when field is a type, not a mixin.Try using an alias parameter: struct vectorspace(alias field) { mixin field; }I would like to weigh in for struct inheritance, since it seems a trivial thing to allow. C programmers have often done this by declaring a variable of the base type as the first member of the struct. So I was a little surprised that D has no inheritance for plain data structs.I agree that struct inheritance would be useful.There is more missing in D that prevents me to port the system fully: - explicit return by reference (return an L-value) - struct constructors These are not showblockers, but missing them is ugly!I agree. Those have both been discussed several times. One common implication of not having l-value returns is: struct point { int x,y; } ... MyArray!(point) arr; ... arr[5].x = 3; // no effectThe explicit L-value return however I think is an important concept that is missing with subtle implications. Without it, user defined types can never be made transparent to builtin types. Consider: int a; (+a) = 3; The unary plus operator returns an L-value, so the assignment can take place. In C++, you can define the unary + operator to behave the same for your type, by defining both R-value and L-value operator: // R-value unary + const mytype &operator +( const mytype &object ) { return object; } // L-value unary + mytype &operator +( mytype &object ) { return object; } In D, you can only do the R-value version.Yes. This is the area where I find D most lacking. /Oskar
Jun 13 2006
Oskar Linde wrote:cschueler skrev:Write MyArray.opIndex to return a pointer and it will work. I do still agree with the proposal, however. -- Chris Nicholson-SaulsThere is more missing in D that prevents me to port the system fully: - explicit return by reference (return an L-value) - struct constructors These are not showblockers, but missing them is ugly!I agree. Those have both been discussed several times. One common implication of not having l-value returns is: struct point { int x,y; } .... MyArray!(point) arr; .... arr[5].x = 3; // no effect
Jun 13 2006
Chris Nicholson-Sauls skrev:Oskar Linde wrote:That will work in this case, but will break the rvalue case instead: point pt = arr[6]; /Oskarcschueler skrev:Write MyArray.opIndex to return a pointer and it will work. I do still agree with the proposal, however.There is more missing in D that prevents me to port the system fully: - explicit return by reference (return an L-value) - struct constructors These are not showblockers, but missing them is ugly!I agree. Those have both been discussed several times. One common implication of not having l-value returns is: struct point { int x,y; } .... MyArray!(point) arr; .... arr[5].x = 3; // no effect
Jun 13 2006
On Tue, 13 Jun 2006 18:56:23 +0200, Oskar Linde <oskar.lindeREM OVEgmail.com> wrote:Chris Nicholson-Sauls skrev:point pt = *arr[6]; should work. ReganOskar Linde wrote:That will work in this case, but will break the rvalue case instead: point pt = arr[6];cschueler skrev:Write MyArray.opIndex to return a pointer and it will work. I do still agree with the proposal, however.There is more missing in D that prevents me to port the system fully: - explicit return by reference (return an L-value) - struct constructors These are not showblockers, but missing them is ugly!I agree. Those have both been discussed several times. One common implication of not having l-value returns is: struct point { int x,y; } .... MyArray!(point) arr; .... arr[5].x = 3; // no effect
Jun 13 2006