Why can't structs be derived from?

Steven Schveighoffer schveiguy at yahoo.com
Wed Mar 16 08:23:47 PDT 2011


On Wed, 16 Mar 2011 11:01:18 -0400, Ary Manzana <ary at esperanto.org.ar>  
wrote:

> On 3/15/11 3:29 PM, Andrei Alexandrescu wrote:
>> On 3/15/11 12:55 PM, Jens wrote:
>>> Steven Schveighoffer wrote:
>>>> That's all there is. Structs do not have inheritance, only alias
>>>> this.
>>>
>>> Why don't they though? Inheritance does not have to mean polymorphic.  
>>> It
>>> can mean composition, like in C++. I don't understand the reason for  
>>> such
>>> ugly syntax.
>>
>> Using inheritance for composition is frowned upon in C++ for good
>> reasons. If you want composition, the best is to use composition.
>>
>> The reason for the allegedly ugly syntax is that it's considerably more
>> general. It is often the case that a struct defines an entity that is
>> implicitly convertible to another entity - could be an rvalue vs.
>> lvalue, a class vs. another struct vs. a primitive type, could need a
>> run-time operation etc. Inheritance would offer at best few of these
>> amenities, whereas 'alias this' offers all with a simple syntax.
>>
>>
>> Andrei
>
> Syntax matters. A lot. Which one is more readable/understandable?
>
> struct Point2 {
>    int x;
>    int y;
> }
>
> 1.
>
> struct Point3 {
>    Point2 point2;
>    alias this point2;
>    int z;
> }
>
> 2.
>
> struct Point3 : Point2 {
>    int z;
> }
>
> You can't deny this last one is much more easier to understand and it  
> exactly does what your mind want to do: just give me what's in the other  
> struct and let me add more things.

Yes, it is clearer to understand.  But there are good reasons not to allow  
this as I outline below.

> The compiler can implement this using alias this and making the aliased  
> member private, and possibly disallowing adding another alias this.

struct Point2 {
    int x, y;
    void draw(Canvas c) {...}
}

struct Point3 : Point2 {
    int z;
    void draw(Canvas c) {...}
}

Point3 p3;
Point2 *p2 = &p3;

// what does this do?
p2.draw(c);

The problem is, inheritance implies polymorphism in D, and other languages  
like D (C#, Java).  If we allow composition by inheritance on structs,  
then people will be confused as to why polymorphism isn't working on  
structs.  I think allowing inheritance in structs and not allowing  
polymorphism is a much more difficult position to defend, and we don't  
want to go there.  Just not allowing inheritance works well, and alias  
this does implement the desired usage syntax, along with other benefits.

Also IMO, the syntax help comes more on the using end than the defining  
end.  That is, the huge benefit of composition by derivation is I can do

p3.x = 5;

instead of

p3.point2.x = 5;

Not that the definition looks pretty.  Once I know that Point3 is also a  
Point2, I'm never looking at that definition again.

I don't think this issue is worth changing anything over.  Syntax is  
important, but the minor syntax improvement here does not outweigh the  
cost of opening the can of polymorphic struct worms.

Besides, I feel that alias this is more in line with what you are trying  
to do when you use inheritance to extend a type -- I want to alias the  
namespace of the given target into my own namespace.

BTW, before alias this was around, I lamented for this exact feature  
(struct extension via inheritance), but I think alias this covers it quite  
well.

-Steve


More information about the Digitalmars-d mailing list