www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Why can't structs be derived from?

reply "Jens" <jne somewhere.org> writes:
It seems rather fundamental to be able to compose a new struct from a 
given struct using inheritance. Why is this not allowed?

struct slist_node
{
    slist_node* next;
};

template <class T>
struct slist_node<T>: public slist_node
{
    T data;
}; 
Mar 15 2011
next sibling parent reply dsimcha <dsimcha yahoo.com> writes:
On 3/15/2011 9:25 AM, Jens wrote:
 It seems rather fundamental to be able to compose a new struct from a
 given struct using inheritance. Why is this not allowed?

 struct slist_node
 {
      slist_node* next;
 };

 template<class T>
 struct slist_node<T>: public slist_node
 {
      T data;
 };

Something that has basically that effect is allowed, just not with that syntax: struct slist_node(T) { slist_node base; alias base this; T data; }
Mar 15 2011
next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 15 Mar 2011 09:28:50 -0400, dsimcha <dsimcha yahoo.com> wrote:

 On 3/15/2011 9:25 AM, Jens wrote:
 It seems rather fundamental to be able to compose a new struct from a
 given struct using inheritance. Why is this not allowed?

 struct slist_node
 {
      slist_node* next;
 };

 template<class T>
 struct slist_node<T>: public slist_node
 {
      T data;
 };

Something that has basically that effect is allowed, just not with that syntax: struct slist_node(T) { slist_node base; alias base this; T data; }

Wow, I find it strange that we came up with the almost the same code ;) -Steve
Mar 15 2011
prev sibling next sibling parent reply "Jens" <jne somewhere.org> writes:
dsimcha wrote:
 On 3/15/2011 9:25 AM, Jens wrote:
 It seems rather fundamental to be able to compose a new struct from a
 given struct using inheritance. Why is this not allowed?

 struct slist_node
 {
      slist_node* next;
 };

 template<class T>
 struct slist_node<T>: public slist_node
 {
      T data;
 };

Something that has basically that effect is allowed, just not with that syntax: struct slist_node(T) { slist_node base; alias base this; T data; }

That's ugly.
Mar 15 2011
parent reply "Jens" <jne somewhere.org> writes:
Steven Schveighoffer wrote:
 On Tue, 15 Mar 2011 13:30:00 -0400, Jens <jne somewhere.org> wrote:

 dsimcha wrote:
 On 3/15/2011 9:25 AM, Jens wrote:
 It seems rather fundamental to be able to compose a new struct
 from a given struct using inheritance. Why is this not allowed?

 struct slist_node
 {
      slist_node* next;
 };

 template<class T>
 struct slist_node<T>: public slist_node
 {
      T data;
 };

Something that has basically that effect is allowed, just not with that syntax: struct slist_node(T) { slist_node base; alias base this; T data; }

That's ugly.

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.
Mar 15 2011
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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
Mar 15 2011
next sibling parent reply "Jens" <jne somewhere.org> writes:
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.

It was frowned upon early on because the compiler implementers didn't have their acts together and the resulting objects layout could not be relied upon. The example I gave came from the STL so I think "frowned upon" is something you are picking up from long ago. Composition means access through the members rather than direct access: struct point { int x; int y; }; struct point3d { point pt; int z; }; ... point3d mypoint; mypoint.pt.x = 3; // ugly
 The reason for the allegedly ugly syntax is that it's considerably
 more general.

Over-generality is a key thing that gets languages in trouble.
 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.

What's wrong with conversion operators? I wouldn't use "simple" and "ugly" in the same sentence. I would have chosen a different design.
Mar 15 2011
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 03/15/2011 01:48 PM, Jens wrote:
 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.

It was frowned upon early on because the compiler implementers didn't have their acts together and the resulting objects layout could not be relied upon.

That's not the reason at all.
 The example I gave came from the STL so I think "frowned
 upon" is something you are picking up from long ago.

STL's mild abuses of inheritance (in the absence of something better such as aliases) are known and understood without being condoned at large. For a good account of why composition is preferable to inheritance, you may want to refer to http://www.artima.com/cppsource/codestandards3.html and the referred bibliography.
 Composition means access through the members rather than direct access:

 struct point
 {
      int x;
      int y;
 };

 struct point3d
 {
      point pt;
      int z;
 };

 ...

 point3d mypoint;
 mypoint.pt.x = 3; // ugly

 The reason for the allegedly ugly syntax is that it's considerably
 more general.

Over-generality is a key thing that gets languages in trouble.

This is general enough to be too vacuous. We figured we need a better subtyping mechanism for structs and designed 'alias this' for that purpose. How is this getting D in trouble?
 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.

What's wrong with conversion operators? I wouldn't use "simple" and "ugly" in the same sentence. I would have chosen a different design.

Please give detail on the design you would have chosen, thanks. Andrei
Mar 15 2011
parent reply "Jens" <jne somewhere.org> writes:
Andrei Alexandrescu wrote:
 On 03/15/2011 01:48 PM, Jens wrote:
 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.

It was frowned upon early on because the compiler implementers didn't have their acts together and the resulting objects layout could not be relied upon.

That's not the reason at all.
 The example I gave came from the STL so I think "frowned
 upon" is something you are picking up from long ago.

STL's mild abuses of inheritance (in the absence of something better such as aliases) are known and understood without being condoned at large. For a good account of why composition is preferable to inheritance, you may want to refer to http://www.artima.com/cppsource/codestandards3.html and the referred bibliography.

Knowing where to break from "absolutisms" is important. There's nothing wrong with doing extension of structs via derivation.
 Composition means access through the members rather than direct
 access: struct point
 {
      int x;
      int y;
 };

 struct point3d
 {
      point pt;
      int z;
 };

 ...

 point3d mypoint;
 mypoint.pt.x = 3; // ugly

 The reason for the allegedly ugly syntax is that it's considerably
 more general.

Over-generality is a key thing that gets languages in trouble.

This is general enough to be too vacuous.

It is easily observable. Knowing where to draw the lines is key. In this instance, I think he blew it.
 We figured we need a better
 subtyping mechanism for structs and designed 'alias this' for that
 purpose. How is this getting D in trouble?

I won't use it.
 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.

What's wrong with conversion operators? I wouldn't use "simple" and "ugly" in the same sentence. I would have chosen a different design.

Please give detail on the design you would have chosen, thanks.

I have no problem with a C++-like way. I think it needed not been drastically departed from. I have an object model planned but I'm not about to detail it here. Sometimes I wonder if D has the goal of changing as much as possible just for change sake.
Mar 15 2011
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Jens:

 Sometimes I wonder if D has the goal of changing 
 as much as possible just for change sake. 

I don't think so. Several D problems come from C syntax/semantics. Bye, bearophile
Mar 15 2011
parent "Jens" <jne somewhere.org> writes:
bearophile wrote:
 Jens:

 Sometimes I wonder if D has the goal of changing
 as much as possible just for change sake.

I don't think so. Several D problems come from C syntax/semantics.

May be just too late to change those now.
Mar 15 2011
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 3/15/11 2:07 PM, Jens wrote:
 Andrei Alexandrescu wrote:
 STL's mild abuses of inheritance (in the absence of something better
 such as aliases) are known and understood without being condoned at
 large. For a good account of why composition is preferable to
 inheritance, you may want to refer to
 http://www.artima.com/cppsource/codestandards3.html and the referred
 bibliography.

Knowing where to break from "absolutisms" is important. There's nothing wrong with doing extension of structs via derivation.

With amendments (data protection, lvalue vs. rvalue access, hooks upon conversion to base...), sure. That's why we included alias this as a mechanism that encompasses such functionality (including user-controlled conversions) without adding one language feature for each.
 Composition means access through the members rather than direct
 access: struct point
 {
       int x;
       int y;
 };

 struct point3d
 {
       point pt;
       int z;
 };

 ...

 point3d mypoint;
 mypoint.pt.x = 3; // ugly

 The reason for the allegedly ugly syntax is that it's considerably
 more general.

Over-generality is a key thing that gets languages in trouble.

This is general enough to be too vacuous.

It is easily observable. Knowing where to draw the lines is key. In this instance, I think he blew it.

He being whom?
 We figured we need a better
 subtyping mechanism for structs and designed 'alias this' for that
 purpose. How is this getting D in trouble?

I won't use it.

How is you not using 'alias this' is getting D in trouble?
 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.

What's wrong with conversion operators? I wouldn't use "simple" and "ugly" in the same sentence. I would have chosen a different design.

Please give detail on the design you would have chosen, thanks.

I have no problem with a C++-like way. I think it needed not been drastically departed from. I have an object model planned but I'm not about to detail it here. Sometimes I wonder if D has the goal of changing as much as possible just for change sake.

You'd have better success with substantiating that point using pretty much any other feature. This is a losing pick. D was designed by people very familiar with C++, appreciative of its qualities, and aware of its issues. A cosmopolitan community also provided input to the design. Inadvertent C++ object slicing was considered (and for good reasons I think) a major issue in C++ that needed to be addressed. There would definitely be several ways of addressing it, but using sheer inheritance for polymorphic classes and 'alias this' for monomorphic structs is a very robust combination. Andrei
Mar 15 2011
parent "Jens" <jne somewhere.org> writes:
Andrei Alexandrescu wrote:
 On 3/15/11 2:07 PM, Jens wrote:
 Andrei Alexandrescu wrote:
 STL's mild abuses of inheritance (in the absence of something better
 such as aliases) are known and understood without being condoned at
 large. For a good account of why composition is preferable to
 inheritance, you may want to refer to
 http://www.artima.com/cppsource/codestandards3.html and the referred
 bibliography.

Knowing where to break from "absolutisms" is important. There's nothing wrong with doing extension of structs via derivation.

With amendments (data protection, lvalue vs. rvalue access, hooks upon conversion to base...), sure. That's why we included alias this as a mechanism that encompasses such functionality (including user-controlled conversions) without adding one language feature for each.

The concept begs for a non-keyword-within-the-struct syntax, IMO. That you don't mind looking at it is fine. I can't stand it.
 Composition means access through the members rather than direct
 access: struct point
 {
       int x;
       int y;
 };

 struct point3d
 {
       point pt;
       int z;
 };

 ...

 point3d mypoint;
 mypoint.pt.x = 3; // ugly

 The reason for the allegedly ugly syntax is that it's considerably
 more general.

Over-generality is a key thing that gets languages in trouble.

This is general enough to be too vacuous.

It is easily observable. Knowing where to draw the lines is key. In this instance, I think he blew it.

He being whom?

Walter or you or whoever screwed that one up.
 We figured we need a better
 subtyping mechanism for structs and designed 'alias this' for that
 purpose. How is this getting D in trouble?

I won't use it.

How is you not using 'alias this' is getting D in trouble?

I meant using D.
 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.

What's wrong with conversion operators? I wouldn't use "simple" and "ugly" in the same sentence. I would have chosen a different design.

Please give detail on the design you would have chosen, thanks.

I have no problem with a C++-like way. I think it needed not been drastically departed from. I have an object model planned but I'm not about to detail it here. Sometimes I wonder if D has the goal of changing as much as possible just for change sake.

You'd have better success with substantiating that point using pretty much any other feature. This is a losing pick.

I don't know what you mean. Or what part did you not understand?
 D was designed by people very familiar with C++, appreciative of its
 qualities, and aware of its issues. A cosmopolitan community also
 provided input to the design. Inadvertent C++ object slicing was
 considered (and for good reasons I think) a major issue in C++ that
 needed to be addressed. There would definitely be several ways of
 addressing it, but using sheer inheritance for polymorphic classes and
 'alias this' for monomorphic structs is a very robust combination.

Are you over-emphasizing "the slicing problem" to justify D's solution to it?
Mar 15 2011
prev sibling parent reply Daniel Gibson <metalcaedes gmail.com> writes:
Am 15.03.2011 19:48, schrieb Jens:
 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.

It was frowned upon early on because the compiler implementers didn't have their acts together and the resulting objects layout could not be relied upon. The example I gave came from the STL so I think "frowned upon" is something you are picking up from long ago. Composition means access through the members rather than direct access: struct point { int x; int y; }; struct point3d { point pt; int z; }; ... point3d mypoint; mypoint.pt.x = 3; // ugly

This is why you add "alias pt this;" to point3d. So you can write mypoint.x = 3; Cheers, - Daniel
Mar 15 2011
parent reply "Jens" <jne somewhere.org> writes:
Daniel Gibson wrote:
 Am 15.03.2011 19:48, schrieb Jens:
 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.

It was frowned upon early on because the compiler implementers didn't have their acts together and the resulting objects layout could not be relied upon. The example I gave came from the STL so I think "frowned upon" is something you are picking up from long ago. Composition means access through the members rather than direct access: struct point { int x; int y; }; struct point3d { point pt; int z; }; ... point3d mypoint; mypoint.pt.x = 3; // ugly

This is why you add "alias pt this;" to point3d. So you can write mypoint.x = 3;

Still ugly though.
Mar 15 2011
next sibling parent reply Daniel Gibson <metalcaedes gmail.com> writes:
Am 15.03.2011 20:24, schrieb Jens:
 Daniel Gibson wrote:
 Am 15.03.2011 19:48, schrieb Jens:
 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.

It was frowned upon early on because the compiler implementers didn't have their acts together and the resulting objects layout could not be relied upon. The example I gave came from the STL so I think "frowned upon" is something you are picking up from long ago. Composition means access through the members rather than direct access: struct point { int x; int y; }; struct point3d { point pt; int z; }; ... point3d mypoint; mypoint.pt.x = 3; // ugly

This is why you add "alias pt this;" to point3d. So you can write mypoint.x = 3;

Still ugly though.

I don't think so. It makes obvious what happens: a composition - *not* an inheritance - with syntactic sugar that allows one to omit the .pt in mypoint.(pt.)x - as long as mypoint doesn't have a member x itself. Allowing inheritance syntax on structs would only lead to confusion - especially for people coming from C++. Cheers, - Daniel
Mar 15 2011
parent reply "Jens" <jne somewhere.org> writes:
Daniel Gibson wrote:
 Am 15.03.2011 20:24, schrieb Jens:
 Daniel Gibson wrote:
 Am 15.03.2011 19:48, schrieb Jens:
 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.

It was frowned upon early on because the compiler implementers didn't have their acts together and the resulting objects layout could not be relied upon. The example I gave came from the STL so I think "frowned upon" is something you are picking up from long ago. Composition means access through the members rather than direct access: struct point { int x; int y; }; struct point3d { point pt; int z; }; ... point3d mypoint; mypoint.pt.x = 3; // ugly

This is why you add "alias pt this;" to point3d. So you can write mypoint.x = 3;

Still ugly though.

I don't think so. It makes obvious what happens: a composition - *not* an inheritance - with syntactic sugar that allows one to omit the .pt in mypoint.(pt.)x - as long as mypoint doesn't have a member x itself.

YMMV. To me it's ugly enough to not take the language seriously.
 Allowing inheritance syntax on structs would only lead to confusion -
 especially for people coming from C++.

C++ does it that way, so what confusion are you talking about?
Mar 15 2011
parent reply Daniel Gibson <metalcaedes gmail.com> writes:
Am 15.03.2011 20:40, schrieb Jens:
 Daniel Gibson wrote:
 Am 15.03.2011 20:24, schrieb Jens:
 Daniel Gibson wrote:
 Am 15.03.2011 19:48, schrieb Jens:
 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.

It was frowned upon early on because the compiler implementers didn't have their acts together and the resulting objects layout could not be relied upon. The example I gave came from the STL so I think "frowned upon" is something you are picking up from long ago. Composition means access through the members rather than direct access: struct point { int x; int y; }; struct point3d { point pt; int z; }; ... point3d mypoint; mypoint.pt.x = 3; // ugly

This is why you add "alias pt this;" to point3d. So you can write mypoint.x = 3;

Still ugly though.

I don't think so. It makes obvious what happens: a composition - *not* an inheritance - with syntactic sugar that allows one to omit the .pt in mypoint.(pt.)x - as long as mypoint doesn't have a member x itself.

YMMV. To me it's ugly enough to not take the language seriously.
 Allowing inheritance syntax on structs would only lead to confusion -
 especially for people coming from C++.

C++ does it that way, so what confusion are you talking about?

The confusion that in C++ classes and structs are basically the same (only the default visibility of members is different) while in D they're not. So allowing "inheritance" on structs would give the false impression that structs in D are also classes of some kind. Furthermore I find C++'s class handling quite unfortunate.. only having polymorphism when explicitly using pointers really sucks. e.g. you have a base class Foo and a class Bar derived from Foo.. now you wanna put Objects of type Foo and Bar in a list.. what do you do? list<Foo>? won't work for Bar Objects. So you gotta use list<Foo*>. Using list<Foo*> really sucks, especially with iterators.. you end up using something like list<Foo*>::iterator it = ... ; (*it)->x = 3; int bla = (*it)->myFun(42); Now *that* is ugly.
Mar 15 2011
next sibling parent reply "Jens" <jne somewhere.org> writes:
Daniel Gibson wrote:
 Am 15.03.2011 20:40, schrieb Jens:
 Daniel Gibson wrote:
 Am 15.03.2011 20:24, schrieb Jens:
 Daniel Gibson wrote:
 Am 15.03.2011 19:48, schrieb Jens:
 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.

It was frowned upon early on because the compiler implementers didn't have their acts together and the resulting objects layout could not be relied upon. The example I gave came from the STL so I think "frowned upon" is something you are picking up from long ago. Composition means access through the members rather than direct access: struct point { int x; int y; }; struct point3d { point pt; int z; }; ... point3d mypoint; mypoint.pt.x = 3; // ugly

This is why you add "alias pt this;" to point3d. So you can write mypoint.x = 3;

Still ugly though.

I don't think so. It makes obvious what happens: a composition - *not* an inheritance - with syntactic sugar that allows one to omit the .pt in mypoint.(pt.)x - as long as mypoint doesn't have a member x itself.

YMMV. To me it's ugly enough to not take the language seriously.
 Allowing inheritance syntax on structs would only lead to confusion
 - especially for people coming from C++.

C++ does it that way, so what confusion are you talking about?

The confusion that in C++ classes and structs are basically the same (only the default visibility of members is different) while in D they're not. So allowing "inheritance" on structs would give the false impression that structs in D are also classes of some kind.

Not a good reason to change the syntax. That's what the manual is for. What you said was: "Someone is going to try to program in D without reading the manual and then be surprised when it doesn't work like C++ so we'll just remove the construct so that doesn't happen -- at the expense of elegant syntax".
 Furthermore I find C++'s class handling quite unfortunate..

Me too, some of it.
 only
 having polymorphism when explicitly using pointers really sucks.

How is it different in D where all polymorphic objects are reference types? Take have the design space away, make everything a glorified pointer and things are better?
 e.g. you have a base class Foo and a class Bar derived from Foo.. now
 you wanna put Objects of type Foo and Bar in a list.. what do you do?

We'll have to save container design for another day.
Mar 15 2011
parent reply Daniel Gibson <metalcaedes gmail.com> writes:
Am 15.03.2011 21:07, schrieb Jens:
 Daniel Gibson wrote:
 Am 15.03.2011 20:40, schrieb Jens:
 Daniel Gibson wrote:
 Am 15.03.2011 20:24, schrieb Jens:
 Daniel Gibson wrote:
 Am 15.03.2011 19:48, schrieb Jens:
 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.

It was frowned upon early on because the compiler implementers didn't have their acts together and the resulting objects layout could not be relied upon. The example I gave came from the STL so I think "frowned upon" is something you are picking up from long ago. Composition means access through the members rather than direct access: struct point { int x; int y; }; struct point3d { point pt; int z; }; ... point3d mypoint; mypoint.pt.x = 3; // ugly

This is why you add "alias pt this;" to point3d. So you can write mypoint.x = 3;

Still ugly though.

I don't think so. It makes obvious what happens: a composition - *not* an inheritance - with syntactic sugar that allows one to omit the .pt in mypoint.(pt.)x - as long as mypoint doesn't have a member x itself.

YMMV. To me it's ugly enough to not take the language seriously.
 Allowing inheritance syntax on structs would only lead to confusion
 - especially for people coming from C++.

C++ does it that way, so what confusion are you talking about?

The confusion that in C++ classes and structs are basically the same (only the default visibility of members is different) while in D they're not. So allowing "inheritance" on structs would give the false impression that structs in D are also classes of some kind.

Not a good reason to change the syntax. That's what the manual is for. What you said was: "Someone is going to try to program in D without reading the manual and then be surprised when it doesn't work like C++ so we'll just remove the construct so that doesn't happen -- at the expense of elegant syntax".
 Furthermore I find C++'s class handling quite unfortunate..

Me too, some of it.
 only
 having polymorphism when explicitly using pointers really sucks.

How is it different in D where all polymorphic objects are reference types? Take have the design space away, make everything a glorified pointer and things are better?

They obviously are. Successful languages like Java and C# do it. It's less error-prone and you don't have to worry about dereferencing stuff all the time (sometimes even multiple dereferences at once, like in my example).
 
 e.g. you have a base class Foo and a class Bar derived from Foo.. now
 you wanna put Objects of type Foo and Bar in a list.. what do you do?

We'll have to save container design for another day.

Mar 15 2011
parent reply "Jens" <jne somewhere.org> writes:
Daniel Gibson wrote:
 Am 15.03.2011 21:07, schrieb Jens:
 Daniel Gibson wrote:
 Am 15.03.2011 20:40, schrieb Jens:
 Daniel Gibson wrote:
 Am 15.03.2011 20:24, schrieb Jens:
 Daniel Gibson wrote:
 Am 15.03.2011 19:48, schrieb Jens:
 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.

It was frowned upon early on because the compiler implementers didn't have their acts together and the resulting objects layout could not be relied upon. The example I gave came from the STL so I think "frowned upon" is something you are picking up from long ago. Composition means access through the members rather than direct access: struct point { int x; int y; }; struct point3d { point pt; int z; }; ... point3d mypoint; mypoint.pt.x = 3; // ugly

This is why you add "alias pt this;" to point3d. So you can write mypoint.x = 3;

Still ugly though.

I don't think so. It makes obvious what happens: a composition - *not* an inheritance - with syntactic sugar that allows one to omit the .pt in mypoint.(pt.)x - as long as mypoint doesn't have a member x itself.

YMMV. To me it's ugly enough to not take the language seriously.
 Allowing inheritance syntax on structs would only lead to
 confusion - especially for people coming from C++.

C++ does it that way, so what confusion are you talking about?

The confusion that in C++ classes and structs are basically the same (only the default visibility of members is different) while in D they're not. So allowing "inheritance" on structs would give the false impression that structs in D are also classes of some kind.

Not a good reason to change the syntax. That's what the manual is for. What you said was: "Someone is going to try to program in D without reading the manual and then be surprised when it doesn't work like C++ so we'll just remove the construct so that doesn't happen -- at the expense of elegant syntax".
 Furthermore I find C++'s class handling quite unfortunate..

Me too, some of it.
 only
 having polymorphism when explicitly using pointers really sucks.

How is it different in D where all polymorphic objects are reference types? Take have the design space away, make everything a glorified pointer and things are better?

They obviously are. Successful languages like Java and C# do it. It's less error-prone and you don't have to worry about dereferencing stuff all the time (sometimes even multiple dereferences at once, like in my example).

More toward Java-class-language then than C++-level language. Sacrificing stack objects was like throwing out sharp knives from the kitchen. I understand.
Mar 15 2011
parent reply Daniel Gibson <metalcaedes gmail.com> writes:
Am 15.03.2011 21:29, schrieb Jens:
 Daniel Gibson wrote:
 Am 15.03.2011 21:07, schrieb Jens:
 How is it different in D where all polymorphic objects are reference
 types? Take have the design space away, make everything a glorified
 pointer and things are better?

They obviously are. Successful languages like Java and C# do it. It's less error-prone and you don't have to worry about dereferencing stuff all the time (sometimes even multiple dereferences at once, like in my example).

More toward Java-class-language then than C++-level language. Sacrificing stack objects was like throwing out sharp knives from the kitchen. I understand.

If you want value types use structs. Maybe with alias this or mixins to "extend" them. Or use emplace (see http://www.digitalmars.com/d/2.0/phobos/std_conv.html ) with classes if you wanna play with sharp tools. It's not like you can't (risk to) cut yourself with D, it's just easier not to.
Mar 15 2011
parent reply "Jens" <jne somewhere.org> writes:
Daniel Gibson wrote:
 Am 15.03.2011 21:29, schrieb Jens:
 Daniel Gibson wrote:
 Am 15.03.2011 21:07, schrieb Jens:
 How is it different in D where all polymorphic objects are
 reference types? Take have the design space away, make everything
 a glorified pointer and things are better?

They obviously are. Successful languages like Java and C# do it. It's less error-prone and you don't have to worry about dereferencing stuff all the time (sometimes even multiple dereferences at once, like in my example).

More toward Java-class-language then than C++-level language. Sacrificing stack objects was like throwing out sharp knives from the kitchen. I understand.

If you want value types use structs. Maybe with alias this or mixins to "extend" them. Or use emplace (see http://www.digitalmars.com/d/2.0/phobos/std_conv.html ) with classes if you wanna play with sharp tools. It's not like you can't (risk to) cut yourself with D, it's just easier not to.

While the above was off-topic, I was alluding to class objects on the stack. So not to turn the thread into a critique of the entire language, I'll leave it at that.
Mar 15 2011
next sibling parent Max Samukha <max spam.box> writes:
On 03/15/2011 10:46 PM, Jens wrote:
 Daniel Gibson wrote:
 Am 15.03.2011 21:29, schrieb Jens:
 Daniel Gibson wrote:
 Am 15.03.2011 21:07, schrieb Jens:
 How is it different in D where all polymorphic objects are
 reference types? Take have the design space away, make everything
 a glorified pointer and things are better?

They obviously are. Successful languages like Java and C# do it. It's less error-prone and you don't have to worry about dereferencing stuff all the time (sometimes even multiple dereferences at once, like in my example).

More toward Java-class-language then than C++-level language. Sacrificing stack objects was like throwing out sharp knives from the kitchen. I understand.

If you want value types use structs. Maybe with alias this or mixins to "extend" them. Or use emplace (see http://www.digitalmars.com/d/2.0/phobos/std_conv.html ) with classes if you wanna play with sharp tools. It's not like you can't (risk to) cut yourself with D, it's just easier not to.

While the above was off-topic, I was alluding to class objects on the stack. So not to turn the thread into a critique of the entire language, I'll leave it at that.

Class objects are possible on stack in D.
Mar 15 2011
prev sibling next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Tuesday, March 15, 2011 14:15:48 Max Samukha wrote:
 On 03/15/2011 10:46 PM, Jens wrote:
 Daniel Gibson wrote:
 Am 15.03.2011 21:29, schrieb Jens:
 Daniel Gibson wrote:
 Am 15.03.2011 21:07, schrieb Jens:
 How is it different in D where all polymorphic objects are
 reference types? Take have the design space away, make everything
 a glorified pointer and things are better?

They obviously are. Successful languages like Java and C# do it. It's less error-prone and you don't have to worry about dereferencing stuff all the time (sometimes even multiple dereferences at once, like in my example).

More toward Java-class-language then than C++-level language. Sacrificing stack objects was like throwing out sharp knives from the kitchen. I understand.

If you want value types use structs. Maybe with alias this or mixins to "extend" them. Or use emplace (see http://www.digitalmars.com/d/2.0/phobos/std_conv.html ) with classes if you wanna play with sharp tools. It's not like you can't (risk to) cut yourself with D, it's just easier not to.

While the above was off-topic, I was alluding to class objects on the stack. So not to turn the thread into a critique of the entire language, I'll leave it at that.

Class objects are possible on stack in D.

Yes, but only with the help of the standard library: std.typecons.scoped. scoped classes are going to be removed from the language. It really shouldn't normally be the case that a class object is put on the case. - Jonathan M Davis
Mar 15 2011
parent reply "Jens" <jne somewhere.org> writes:
Jonathan M Davis wrote:
 On Tuesday, March 15, 2011 14:15:48 Max Samukha wrote:
 On 03/15/2011 10:46 PM, Jens wrote:
 Daniel Gibson wrote:
 Am 15.03.2011 21:29, schrieb Jens:
 Daniel Gibson wrote:
 Am 15.03.2011 21:07, schrieb Jens:
 How is it different in D where all polymorphic objects are
 reference types? Take have the design space away, make
 everything a glorified pointer and things are better?

They obviously are. Successful languages like Java and C# do it. It's less error-prone and you don't have to worry about dereferencing stuff all the time (sometimes even multiple dereferences at once, like in my example).

More toward Java-class-language then than C++-level language. Sacrificing stack objects was like throwing out sharp knives from the kitchen. I understand.

If you want value types use structs. Maybe with alias this or mixins to "extend" them. Or use emplace (see http://www.digitalmars.com/d/2.0/phobos/std_conv.html ) with classes if you wanna play with sharp tools. It's not like you can't (risk to) cut yourself with D, it's just easier not to.

While the above was off-topic, I was alluding to class objects on the stack. So not to turn the thread into a critique of the entire language, I'll leave it at that.

Class objects are possible on stack in D.

Yes, but only with the help of the standard library: std.typecons.scoped. scoped classes are going to be removed from the language. It really shouldn't normally be the case that a class object is put on the case.

And the language-idiomatic things are the ones to focus on rather than "it can be done".
Mar 15 2011
parent reply Daniel Gibson <metalcaedes gmail.com> writes:
Am 15.03.2011 22:46, schrieb Jens:
 Jonathan M Davis wrote:
 On Tuesday, March 15, 2011 14:15:48 Max Samukha wrote:
 Class objects are possible on stack in D.

Yes, but only with the help of the standard library: std.typecons.scoped. scoped classes are going to be removed from the language. It really shouldn't normally be the case that a class object is put on the case.

And the language-idiomatic things are the ones to focus on rather than "it can be done".

Right. And D is not C++ so you shouldn't try to do everything exactly like in C++, D has its own idioms. As said before: You can do almost everything in D that you can do in C++ (except for multiple inheritance, but you can kind-of do that with alias this), but it often is preferred to do stuff differently.
Mar 15 2011
next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Tuesday, March 15, 2011 15:34:50 Andrej Mitrovic wrote:
 Speaking of structs, shouldn't it be possible to write this:?
 
 struct AAWrapper(KeyType, ValType)
 {
     ValType[][KeyType] payload;
     alias payload.opIndex opIndex;
 }
 
 The reasoning behind this is that opIndex in AAWrapper really just
 forwards to payload's opIndex, while other functions like
 opIndexAssign would be specialized in AAWrapper. This currently does
 not compile though.

Does the built in AA even really have an opIndex as far as the compiler is concerned? It would have to have that exact name for that to work, I believe. - Jonathan M Davis
Mar 15 2011
prev sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 3/16/11, Jonathan M Davis <jmdavisProg gmx.com> wrote:
 On Tuesday, March 15, 2011 15:34:50 Andrej Mitrovic wrote:
 Speaking of structs, shouldn't it be possible to write this:?

 struct AAWrapper(KeyType, ValType)
 {
     ValType[][KeyType] payload;
     alias payload.opIndex opIndex;
 }

 The reasoning behind this is that opIndex in AAWrapper really just
 forwards to payload's opIndex, while other functions like
 opIndexAssign would be specialized in AAWrapper. This currently does
 not compile though.

Does the built in AA even really have an opIndex as far as the compiler is concerned? It would have to have that exact name for that to work, I believe. - Jonathan M Davis

It looks like its hidden from the user. From what I can tell what's exposed to the user is AssociativeArray!() from object_.d, and there's no opIndex there. Oh well. :)
Mar 15 2011
prev sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Speaking of structs, shouldn't it be possible to write this:?

struct AAWrapper(KeyType, ValType)
{
    ValType[][KeyType] payload;
    alias payload.opIndex opIndex;
}

The reasoning behind this is that opIndex in AAWrapper really just
forwards to payload's opIndex, while other functions like
opIndexAssign would be specialized in AAWrapper. This currently does
not compile though.
Mar 15 2011
prev sibling parent =?ISO-8859-15?Q?Ali_=C7ehreli?= <acehreli yahoo.com> writes:
On 03/15/2011 12:54 PM, Daniel Gibson wrote:

 Furthermore I find C++'s class handling quite unfortunate.. only having
 polymorphism when explicitly using pointers really sucks.
 e.g. you have a base class Foo and a class Bar derived from Foo.. now 

 put Objects of type Foo and Bar in a list.. what do you do?
 list<Foo>? won't work for Bar Objects. So you gotta use list<Foo*>.
 Using list<Foo*>  really sucks, especially with iterators.. you end 

 something like
    list<Foo*>::iterator it = ... ;
    (*it)->x = 3;
    int bla = (*it)->myFun(42);

 Now *that* is ugly.

I am changing the topic here a little but C++ has more problems as witnessed in the above code. Normally the objects in the list are created by 'new', and not exception-safe for that reason to be left naked in a list. A safe idiom is to use a copyable smart pointer, e.g. list<shared_ptr<Foo> >::iterator it = ...; D's classes' being reference types and its garbage collector help a lot in that regard: list!Foo myList; // can hold Bars too But that's a different topic... :) Ali
Mar 15 2011
prev sibling parent FeepingCreature <default_357-line yahoo.de> writes:
On 15.03.2011 20:24, Jens wrote:
 Daniel Gibson wrote:
 Am 15.03.2011 19:48, schrieb Jens:
 This is why you add "alias pt this;" to point3d. So you can write
  mypoint.x = 3;

Still ugly though.

Quit yer yapping and learn to live with it. ;-)
Mar 16 2011
prev sibling next sibling parent reply Steven Wawryk <stevenw acres.com.au> writes:
On 16/03/11 04:59, Andrei Alexandrescu wrote:
 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.

More general?! How would you express the equivalent of static_cast<slist_node<T> >(base) in the original sample code?
Mar 15 2011
parent Steven Wawryk <stevenw acres.com.au> writes:
On 16/03/11 10:30, Steven Wawryk wrote:
 On 16/03/11 04:59, Andrei Alexandrescu wrote:
 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.

More general?! How would you express the equivalent of static_cast<slist_node<T> >(base) in the original sample code?

Sorry, I meant static_cast<slist_node<T> *>(base_ptr).
Mar 15 2011
prev sibling parent reply Ary Manzana <ary esperanto.org.ar> writes:
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. The compiler can implement this using alias this and making the aliased member private, and possibly disallowing adding another alias this.
Mar 16 2011
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 03/16/2011 10:01 AM, Ary Manzana 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. The compiler can implement this using alias this and making the aliased member private, and possibly disallowing adding another alias this.

The main issue is that inheritance is a very blunt tool. It is so much so that today it is much less applicable than it had been previously thought. alias this provides the degree of control necessary. So the comparison is apples to oranges - it compares all inheritance can do with a minor case of alias this. Andrei
Mar 16 2011
prev sibling next sibling parent Ary Manzana <ary esperanto.org.ar> writes:
On 3/16/11 12:23 PM, Steven Schveighoffer wrote:
 On Wed, 16 Mar 2011 11:01:18 -0400, Ary Manzana <ary 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

Now I get it. Thanks for the explanation :-) Though I always feels like D gives you the tools to accomplish greater things, but you need to write too much too accomplish those things... shortcuts are welcome :-P
Mar 16 2011
prev sibling next sibling parent Piotr Szturmaj <bncrbme jadamspam.pl> writes:
Ary Manzana wrote:
 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.

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

Alias this gives you more power in case of struct serialization. You can place new fields before or after "inherited" struct, or even on both sides. In your 2nd case, z will be always after x and y.
Mar 16 2011
prev sibling next sibling parent reply KennyTM~ <kennytm gmail.com> writes:
On Mar 16, 11 23:01, Ary Manzana 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;

Should be "alias point2 this;" (strengthening the argument that this syntax is not good?)
 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.

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

Mar 16 2011
parent reply "Nick Sabalausky" <a a.a> writes:
"KennyTM~" <kennytm gmail.com> wrote in message 
news:ilrght$1h5i$1 digitalmars.com...
 On Mar 16, 11 23:01, Ary Manzana 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;

Should be "alias point2 this;" (strengthening the argument that this syntax is not good?)

I've long been convinced that "alias old new;" should really be "alias new = old;" The current way confuses me, and I *still* have to consciously stop and think about it every time I write an alias statement (including just now).
Mar 16 2011
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 3/17/11 11:21 AM, Andrej Mitrovic wrote:
 On 3/17/11, Nick Sabalausky<a a.a>  wrote:
 I've long been convinced that "alias old new;" should really be "alias new =
 old;" The current way confuses me, and I *still* have to consciously stop
 and think about it every time I write an alias statement (including just
 now).

I thought I was the only one. The `alias symbol this` in structs in particular always stops me and I have to think about what it means, even though it might be obvious.

I'm with y'all too. Even Walter needs to stop and think for a second. We're considering enabling alias a = b; as an equivalent for alias b a; Andrei
Mar 17 2011
next sibling parent Don <nospam nospam.com> writes:
Andrei Alexandrescu wrote:
 On 3/17/11 11:21 AM, Andrej Mitrovic wrote:
 On 3/17/11, Nick Sabalausky<a a.a>  wrote:
 I've long been convinced that "alias old new;" should really be 
 "alias new =
 old;" The current way confuses me, and I *still* have to consciously 
 stop
 and think about it every time I write an alias statement (including just
 now).

I thought I was the only one. The `alias symbol this` in structs in particular always stops me and I have to think about what it means, even though it might be obvious.

I'm with y'all too. Even Walter needs to stop and think for a second. We're considering enabling alias a = b; as an equivalent for alias b a; Andrei

That would be great!
Mar 17 2011
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Thursday 17 March 2011 22:12:17 Don wrote:
 Andrei Alexandrescu wrote:
 On 3/17/11 11:21 AM, Andrej Mitrovic wrote:
 On 3/17/11, Nick Sabalausky<a a.a>  wrote:
 I've long been convinced that "alias old new;" should really be
 "alias new =
 old;" The current way confuses me, and I *still* have to consciously
 stop
 and think about it every time I write an alias statement (including
 just now).

I thought I was the only one. The `alias symbol this` in structs in particular always stops me and I have to think about what it means, even though it might be obvious.

I'm with y'all too. Even Walter needs to stop and think for a second. We're considering enabling alias a = b; as an equivalent for alias b a; Andrei

That would be great!

Yes. That change would make alias much more pleasant to deal with. It's not all that big a deal with how it is, but I usually screw it up, just like I usually screw up typedefs in C++. It's just not obvious which way it goes. - Jonathan M Davis
Mar 17 2011
prev sibling next sibling parent Bekenn <leaveme alone.com> writes:
On 3/17/2011 2:36 PM, Andrei Alexandrescu wrote:
 I'm with y'all too. Even Walter needs to stop and think for a second.
 We're considering enabling

 alias a = b;

 as an equivalent for

 alias b a;

Please yes. I'd even be in favor of deprecating the old usage, even though every project under the sun (to within experimental error) currently uses it.
Mar 17 2011
prev sibling next sibling parent reply Bekenn <leaveme alone.com> writes:
On 3/17/2011 2:36 PM, Andrei Alexandrescu wrote:
 I'm with y'all too. Even Walter needs to stop and think for a second.
 We're considering enabling

 alias a = b;

 as an equivalent for

 alias b a;

Along similar lines (hoping this isn't too far off-topic), what's the current plan for typedef? I'm aware that it's deprecated (and for good reason), but some of my reading suggests that there's a successor on the horizon.
Mar 18 2011
parent reply "Nick Sabalausky" <a a.a> writes:
"Bekenn" <leaveme alone.com> wrote in message 
news:ilv2pd$1vkd$1 digitalmars.com...
 On 3/17/2011 2:36 PM, Andrei Alexandrescu wrote:
 I'm with y'all too. Even Walter needs to stop and think for a second.
 We're considering enabling

 alias a = b;

 as an equivalent for

 alias b a;

Along similar lines (hoping this isn't too far off-topic), what's the current plan for typedef? I'm aware that it's deprecated (and for good reason), but some of my reading suggests that there's a successor on the horizon.

I was thinking of asking about that, too. Specifically, would it make sence for "typedef b a;" (or "typedef a = b;") to be lowered to something like: struct a { b _tmp; alias _tmp this; } Hmm, then again, IIUC, that would allow 'a' to be implicity converted to 'b' which would defeat half the point, so maybe not.
Mar 18 2011
next sibling parent Don <nospam nospam.com> writes:
Simen kjaeraas wrote:
 On Fri, 18 Mar 2011 15:09:23 +0100, Nick Sabalausky <a a.a> wrote:
 
 "Bekenn" <leaveme alone.com> wrote in message
 news:ilv2pd$1vkd$1 digitalmars.com...
 On 3/17/2011 2:36 PM, Andrei Alexandrescu wrote:
 I'm with y'all too. Even Walter needs to stop and think for a second.
 We're considering enabling

 alias a = b;

 as an equivalent for

 alias b a;

Along similar lines (hoping this isn't too far off-topic), what's the current plan for typedef? I'm aware that it's deprecated (and for good reason), but some of my reading suggests that there's a successor on the horizon.

I was thinking of asking about that, too. Specifically, would it make sence for "typedef b a;" (or "typedef a = b;") to be lowered to something like: struct a { b _tmp; alias _tmp this; } Hmm, then again, IIUC, that would allow 'a' to be implicity converted to 'b' which would defeat half the point, so maybe not.

Yeah. Typedef is too blunt an instrument for our purposes. What we want is: alias Subtype!int SubInt; alias Supertype!int SupInt; alias Standalone!int NaturalNumber; Where the following work: int a = SubInt(3); SupInt b = 3; NaturalNumber c = NaturalNumber(3); and the following do not: SubInt d = 3; int e = SupInt(3); NaturalNumber f = 3; int g = NaturalNumber(3); And of course: alias Subtype!int SubInt2; alias Supertype!int SupInt2; alias Standalone!int NaturalNumber2; Where these do not work: SubInt2 h = SubInt(3); SupInt2 i = SupInt(3); NaturalNumber2 j = NaturalNumber(3);

I think the classic use case for typedef is Windows handles. HMENU menu; HWND window; HANDLE h = menu; // OK h = window; // OK menu = window; // should not compile. My feeling is, that the built-in typedef is just not precise enough to be much use.
Mar 19 2011
prev sibling parent Bekenn <leaveme alone.com> writes:
On 3/18/2011 7:09 AM, Nick Sabalausky wrote:
 "typedef b a;" (or "typedef a = b;")

Regarding syntax, maybe: typedef A : int; typedef B : int; ...with semantics as follows: A a = 5; // ok B b = a; // error int i = a; // ok a = i; // error a = cast(A)i; // ok b = cast(B)a; // error b = cast(B)cast(int)i; // ok Possibly instead of 'typedef' we should be using a non-C keyword. Heck, even 'type' works: type A : int; ...and is more consistent with existing type declarations (we use 'class', 'struct', and 'enum', not 'classdef', 'structdef', and 'enumdef'). Not sure if typedef should work with aggregates; that might just get too confusing. Bleh. Now I'm /really/ off-topic...
Mar 19 2011
prev sibling next sibling parent "Nick Sabalausky" <a a.a> writes:
"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message 
news:iltv3a$2q93$2 digitalmars.com...
 On 3/17/11 11:21 AM, Andrej Mitrovic wrote:
 On 3/17/11, Nick Sabalausky<a a.a>  wrote:
 I've long been convinced that "alias old new;" should really be "alias 
 new =
 old;" The current way confuses me, and I *still* have to consciously 
 stop
 and think about it every time I write an alias statement (including just
 now).

I thought I was the only one. The `alias symbol this` in structs in particular always stops me and I have to think about what it means, even though it might be obvious.

I'm with y'all too. Even Walter needs to stop and think for a second. We're considering enabling alias a = b; as an equivalent for alias b a;

As a minor side-benefit, that would mean that the "alias this" feature *really would* involve the actual code "alias this" ;)
Mar 18 2011
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 3/18/11 3:28 PM, so wrote:
 alias a(T) = b(T, known_type);

 Would it be an overkill?

It's part of the evil plan. Andrei
Mar 18 2011
next sibling parent reply KennyTM~ <kennytm gmail.com> writes:
On Mar 19, 11 04:41, Steven Schveighoffer wrote:
 On Fri, 18 Mar 2011 16:37:49 -0400, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:

 On 3/18/11 3:28 PM, so wrote:
 alias a(T) = b(T, known_type);

 Would it be an overkill?

It's part of the evil plan.

(I think there is a typo above, shouldn't it be alias a(T) = b!(T, known_type) ? ) You mean you would no longer need the surrounding template declaration? i.e. the above (corrected) statement would be short for: template a(T) { alias a = b!(T, known_type); } That would be certainly very un-evil ;) -Steve

Being evil would be: alias staticReduce(alias F, alias Init) = Init; alias staticReduce(alias F, alias Init, T...) if (T.length != 0) = staticReduce!(F, F!(Init, T[0]), T[1..$]); // ^ support conditionals? enum addSize(int total, T) = total + T.sizeof; // ^ yeah why not generalize to enum too? static assert(staticReduce!(addSize, 0, byte, short, int, long[2], float, double) == 35); ;)
Mar 18 2011
next sibling parent "Nick Sabalausky" <a a.a> writes:
"KennyTM~" <kennytm gmail.com> wrote in message 
news:im0gtr$1o3q$1 digitalmars.com...
 On Mar 19, 11 04:41, Steven Schveighoffer wrote:
 On Fri, 18 Mar 2011 16:37:49 -0400, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:

 On 3/18/11 3:28 PM, so wrote:
 alias a(T) = b(T, known_type);

 Would it be an overkill?

It's part of the evil plan.

(I think there is a typo above, shouldn't it be alias a(T) = b!(T, known_type) ? ) You mean you would no longer need the surrounding template declaration? i.e. the above (corrected) statement would be short for: template a(T) { alias a = b!(T, known_type); } That would be certainly very un-evil ;) -Steve

Being evil would be: alias staticReduce(alias F, alias Init) = Init; alias staticReduce(alias F, alias Init, T...) if (T.length != 0) = staticReduce!(F, F!(Init, T[0]), T[1..$]); // ^ support conditionals? enum addSize(int total, T) = total + T.sizeof; // ^ yeah why not generalize to enum too? static assert(staticReduce!(addSize, 0, byte, short, int, long[2], float, double) == 35); ;)

Tasty. I like it.
Mar 19 2011
prev sibling parent "Nick Sabalausky" <a a.a> writes:
"KennyTM~" <kennytm gmail.com> wrote in message 
news:im0gtr$1o3q$1 digitalmars.com...
 enum addSize(int total, T) = total + T.sizeof;

The great thing about that would be decreased need for the terribly non-DRY emonymous template syntax: template addSize(...) { enum addSize = ...; } Ugh. Is there anything in the works to take care of that? It's like C++'s naming system for constructors. I'd even be happier with something like: template addSize(...) { alias _ this; enum _ = ...; } Or maybe if it's grammatically viable: template addSize(...) { enum template = ...; }
Mar 19 2011
prev sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message 
news:im0g0n$1mal$1 digitalmars.com...
 On 3/18/11 3:28 PM, so wrote:
 alias a(T) = b(T, known_type);

 Would it be an overkill?

It's part of the evil plan.

What about stuff like this?: template foo() {} template foo(string str) {} template foo(int i) {} alias foo bar; // use bar!(), bar!("str") and bar!(7) Currently that doesn't work (though I forget exactly how it fails). I've been starting to find that to be more and more of a problem. I don't rememebr if it works or not when foo is series of non-templated function overloads. If not, it should, IMO. Or maybe that would be solved (at least for templates) under the proposed evil plan with something like this?: alias a(T...) = b!(T);
Mar 19 2011
parent reply KennyTM~ <kennytm gmail.com> writes:
On Mar 20, 11 05:14, Nick Sabalausky wrote:
 "Andrei Alexandrescu"<SeeWebsiteForEmail erdani.org>  wrote in message
 news:im0g0n$1mal$1 digitalmars.com...
 On 3/18/11 3:28 PM, so wrote:
 alias a(T) = b(T, known_type);

 Would it be an overkill?

It's part of the evil plan.

What about stuff like this?: template foo() {} template foo(string str) {} template foo(int i) {} alias foo bar; // use bar!(), bar!("str") and bar!(7) Currently that doesn't work (though I forget exactly how it fails). I've been starting to find that to be more and more of a problem. I don't rememebr if it works or not when foo is series of non-templated function overloads. If not, it should, IMO.

Huh? It *does* work. See http://ideone.com/moPhm.
 Or maybe that would be solved (at least for templates) under the proposed
 evil plan with something like this?:

      alias a(T...) = b!(T);

Mar 19 2011
parent "Nick Sabalausky" <a a.a> writes:
"KennyTM~" <kennytm gmail.com> wrote in message 
news:im37b7$i45$1 digitalmars.com...
 On Mar 20, 11 05:14, Nick Sabalausky wrote:
 "Andrei Alexandrescu"<SeeWebsiteForEmail erdani.org>  wrote in message
 news:im0g0n$1mal$1 digitalmars.com...
 On 3/18/11 3:28 PM, so wrote:
 alias a(T) = b(T, known_type);

 Would it be an overkill?

It's part of the evil plan.

What about stuff like this?: template foo() {} template foo(string str) {} template foo(int i) {} alias foo bar; // use bar!(), bar!("str") and bar!(7) Currently that doesn't work (though I forget exactly how it fails). I've been starting to find that to be more and more of a problem. I don't rememebr if it works or not when foo is series of non-templated function overloads. If not, it should, IMO.

Huh? It *does* work. See http://ideone.com/moPhm.

Hmm, weird. That works for me on 2.052, too, and also works with function overloads instead of templates. I could have sworn there was something like that that didn't work. Maybe it was just some corner-case bug. Or maybe I'm just nuts and never did come across such a problem...
Mar 19 2011
prev sibling parent reply KennyTM~ <kennytm gmail.com> writes:
On Mar 19, 11 04:28, so wrote:
 alias a(T) = b(T, known_type);

 Would it be an overkill?

If B is a template I think it's more consistent to add a '!': alias A(T) = B!(T, int); But I don't think it worth such generalization given the existing syntax already works: template A(T) { alias B!(T, int) A; // alias A = B!(T, known_type); }
Mar 18 2011
parent "Nick Sabalausky" <a a.a> writes:
"KennyTM~" <kennytm gmail.com> wrote in message 
news:im0g86$1mr4$1 digitalmars.com...
 On Mar 19, 11 04:28, so wrote:
 alias a(T) = b(T, known_type);

 Would it be an overkill?

If B is a template I think it's more consistent to add a '!': alias A(T) = B!(T, int); But I don't think it worth such generalization given the existing syntax already works: template A(T) { alias B!(T, int) A; // alias A = B!(T, known_type); }

Templated functions already use the same sugar.
Mar 19 2011
prev sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Wednesday, March 16, 2011 16:16:15 KennyTM~ wrote:
 On Mar 16, 11 23:01, Ary Manzana 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;

Should be "alias point2 this;" (strengthening the argument that this syntax is not good?)

It's no worse than C++'s typedef in that regard, and it becomes instantly obviously when you try and compile it, so I don't think that it's ultimately all that much of an issue. - Jonathan M Davis
Mar 16 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 15 Mar 2011 13:30:00 -0400, Jens <jne somewhere.org> wrote:

 dsimcha wrote:
 On 3/15/2011 9:25 AM, Jens wrote:
 It seems rather fundamental to be able to compose a new struct from a
 given struct using inheritance. Why is this not allowed?

 struct slist_node
 {
      slist_node* next;
 };

 template<class T>
 struct slist_node<T>: public slist_node
 {
      T data;
 };

Something that has basically that effect is allowed, just not with that syntax: struct slist_node(T) { slist_node base; alias base this; T data; }

That's ugly.

That's all there is. Structs do not have inheritance, only alias this. -Steve
Mar 15 2011
prev sibling next sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
I've spotted this in QtD's codebase, dunno if this works:

T static_cast(T, U)(U obj)
{
    return cast(T)cast(void*)obj;
}
Mar 15 2011
parent reply bearophile <bearophileHUGS lycos.com> writes:
Andrej Mitrovic:

 I've spotted this in QtD's codebase, dunno if this works:
 
 T static_cast(T, U)(U obj)
 {
     return cast(T)cast(void*)obj;
 }

See this thread, it contains a better implementation of staticCast (partially written by me), that I'd like in Phobos: http://www.digitalmars.com/d/archives/digitalmars/D/learn/Dynamic_and_Static_Casting_24524.html Bye, bearophile
Mar 15 2011
parent reply Daniel Gibson <metalcaedes gmail.com> writes:
Am 16.03.2011 02:01, schrieb bearophile:
 Andrej Mitrovic:

 I've spotted this in QtD's codebase, dunno if this works:

 T static_cast(T, U)(U obj)
 {
      return cast(T)cast(void*)obj;
 }

See this thread, it contains a better implementation of staticCast (partially written by me), that I'd like in Phobos: http://www.digitalmars.com/d/archives/digitalmars/D/learn/Dynamic_and_Static_Casting_24524.html Bye, bearophile

The only difference is that it checks that both T and U are classes and T is the base class of U, or did I miss something? This check may make sense, but this cast could even work on pointers-to-structs if they are similar, something like struct Foo { int x; } struct Bar {int x; int y; } ... Bar *b = new Bar(); b.x = 42; Foo *f = static_cast!(Foo*, Bar*)(b); assert(f !is null); assert(f.x == 42); of course this is kind of ugly and hackish, maybe even non-portable and also works on classes that are not derived from each other without any complaint (that will probably result in strange errors when using methods) - so your version is much safer. Not sure if allowing this kind of casts for (pointers to) structs makes sense - maybe some C-code uses this to emulate inheritance (I seem to recall that Quake2 uses hacks like this)?
Mar 15 2011
parent reply bearophile <bearophileHUGS lycos.com> writes:
Daniel Gibson:

 This check may make sense, but this cast could even work on 
 pointers-to-structs if they are similar, something like

I suggest to keep purposes separated, to keep the semantics of the program cleaner and to avoid some bugs, letting staticCast work with just objects. A different function is for structs, that tests the first fields of the second struct are all present in the same order in the first struct :-) Bye, bearophile
Mar 15 2011
parent Max Samukha <max spam.box> writes:
On 03/16/2011 04:28 AM, bearophile wrote:
 Daniel Gibson:

 This check may make sense, but this cast could even work on
 pointers-to-structs if they are similar, something like

I suggest to keep purposes separated, to keep the semantics of the program cleaner and to avoid some bugs, letting staticCast work with just objects. A different function is for structs, that tests the first fields of the second struct are all present in the same order in the first struct :-) Bye, bearophile

QtD's static_cast is not part of the public API. It is an internal helper function that was supposed to be simple and hacky.
Mar 16 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 15 Mar 2011 20:32:43 -0400, Andrej Mitrovic  
<andrej.mitrovich gmail.com> wrote:

 On 3/15/11, dsimcha <dsimcha yahoo.com> wrote:
 Something that has basically that effect is allowed, just not with that
 syntax:

 struct slist_node(T)
 {
      slist_node base;
      alias base this;

      T data;
 }

Shouldn't base be a pointer? You'll get errors with that code.

The problem is the name. The original code had a simple un-parameterized slist_node type: struct slist_node { slist_node * next; } So when David wrote his response, he meant *that* struct. However, the way he named his parameterized struct, it actually refers to itself. This is the one I wrote, which should be what the OP wanted: struct slist_node_t(T) { slist_node base; alias base this; T data; } -Steve
Mar 16 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Wed, 16 Mar 2011 11:01:18 -0400, Ary Manzana <ary 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
Mar 16 2011
prev sibling next sibling parent "Simen kjaeraas" <simen.kjaras gmail.com> writes:
On Wed, 16 Mar 2011 16:23:47 +0100, Steven Schveighoffer  
<schveiguy yahoo.com> wrote:

 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);

Nothing. You should got a type error upon attempting to assign a p3* to a p2*. -- Simen
Mar 16 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Wed, 16 Mar 2011 16:49:53 -0400, Simen kjaeraas
<simen.kjaras gmail.com> wrote:

 On Wed, 16 Mar 2011 16:23:47 +0100, Steven Schveighoffer  
 <schveiguy yahoo.com> wrote:

 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);

Nothing. You should got a type error upon attempting to assign a p3* to a p2*.

We are assuming struct inheritance works here, as in C++. In C++ I can the address of a derived object to a base class pointer without a cast. This exact code compiles in C++ except for putting semi-colons after the structs (BTW, I have to mention that I freaking LOVE D for eliminating that) and change p2.draw(c) to p2->draw(c). Even if you say that you shouldn't be allowed to do that, then you are going to have complaints as to why it's different from C++... The point is, if we allow inheritance on structs, it causes more confusion to people who expect certain things from inheritance than it beautifies syntax. -Steve
Mar 16 2011
prev sibling next sibling parent "Simen kjaeraas" <simen.kjaras gmail.com> writes:
On Wed, 16 Mar 2011 22:05:49 +0100, Steven Schveighoffer  
<schveiguy yahoo.com> wrote:

 On Wed, 16 Mar 2011 16:49:53 -0400, Simen kjaeraas
 <simen.kjaras gmail.com> wrote:

 On Wed, 16 Mar 2011 16:23:47 +0100, Steven Schveighoffer  
 <schveiguy yahoo.com> wrote:

 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);

Nothing. You should got a type error upon attempting to assign a p3* to a p2*.

We are assuming struct inheritance works here, as in C++. In C++ I can the address of a derived object to a base class pointer without a cast.

And I was assuming we tried to fix C++'s problems in that regard. If we were to use the rule I chose, the slicing problem is moot.
 This exact code compiles in C++ except for putting semi-colons after the  
 structs (BTW, I have to mention that I freaking LOVE D for eliminating  
 that)

I know. It's my number one C/C++ mistake, and same for all students I've had to help (as well as some teachers :).
 and change p2.draw(c) to p2->draw(c).

 Even if you say that you shouldn't be allowed to do that, then you are  
 going to have complaints as to why it's different from C++...

We already have that. Just the other day, some guy named Jens complained that D structs can't be derived from.
 The point is, if we allow inheritance on structs, it causes more  
 confusion to people who expect certain things from inheritance than it  
 beautifies syntax.

I agree. I also prefer alias this, both for its flexibility and its distinctiveness. I just felt that the slicing problem is trivially fixed, and thus need not be a part of the discussion. -- Simen
Mar 16 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Wed, 16 Mar 2011 17:24:34 -0400, Simen kjaeraas  
<simen.kjaras gmail.com> wrote:

 On Wed, 16 Mar 2011 22:05:49 +0100, Steven Schveighoffer  
 <schveiguy yahoo.com> wrote:

 On Wed, 16 Mar 2011 16:49:53 -0400, Simen kjaeraas
 <simen.kjaras gmail.com> wrote:

 On Wed, 16 Mar 2011 16:23:47 +0100, Steven Schveighoffer  
 <schveiguy yahoo.com> wrote:

 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);

Nothing. You should got a type error upon attempting to assign a p3* to a p2*.

confusion to people who expect certain things from inheritance than it beautifies syntax.

I agree. I also prefer alias this, both for its flexibility and its distinctiveness. I just felt that the slicing problem is trivially fixed, and thus need not be a part of the discussion.

The slicing problem is not encountered in this example. Pointing at the base of a derived object does not slice the object. Your rule is too strict ;) -Steve
Mar 16 2011
prev sibling next sibling parent "Simen kjaeraas" <simen.kjaras gmail.com> writes:
On Wed, 16 Mar 2011 22:37:13 +0100, Steven Schveighoffer  
<schveiguy yahoo.com> wrote:

 On Wed, 16 Mar 2011 17:24:34 -0400, Simen kjaeraas  
 <simen.kjaras gmail.com> wrote:
 I agree. I also prefer alias this, both for its flexibility and its
 distinctiveness. I just felt that the slicing problem is trivially  
 fixed,
 and thus need not be a part of the discussion.

The slicing problem is not encountered in this example. Pointing at the base of a derived object does not slice the object. Your rule is too strict ;)

True. I was thinking of the problem of the missing vtable. Related, but not quite the slicing problem. -- Simen
Mar 16 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 3/17/11, Nick Sabalausky <a a.a> wrote:
 I've long been convinced that "alias old new;" should really be "alias new =
 old;" The current way confuses me, and I *still* have to consciously stop
 and think about it every time I write an alias statement (including just
 now).

I thought I was the only one. The `alias symbol this` in structs in particular always stops me and I have to think about what it means, even though it might be obvious.
Mar 17 2011
prev sibling next sibling parent "Regan Heath" <regan netmail.co.nz> writes:
On Thu, 17 Mar 2011 21:36:45 -0000, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 On 3/17/11 11:21 AM, Andrej Mitrovic wrote:
 On 3/17/11, Nick Sabalausky<a a.a>  wrote:
 I've long been convinced that "alias old new;" should really be "alias  
 new =
 old;" The current way confuses me, and I *still* have to consciously  
 stop
 and think about it every time I write an alias statement (including  
 just
 now).

I thought I was the only one. The `alias symbol this` in structs in particular always stops me and I have to think about what it means, even though it might be obvious.

I'm with y'all too. Even Walter needs to stop and think for a second. We're considering enabling alias a = b; as an equivalent for alias b a;

Yes please! -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Mar 18 2011
prev sibling next sibling parent so <so so.so> writes:
alias a(T) = b(T, known_type);

Would it be an overkill?
Mar 18 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 18 Mar 2011 16:37:49 -0400, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 On 3/18/11 3:28 PM, so wrote:
 alias a(T) = b(T, known_type);

 Would it be an overkill?

It's part of the evil plan.

(I think there is a typo above, shouldn't it be alias a(T) = b!(T, known_type) ? ) You mean you would no longer need the surrounding template declaration? i.e. the above (corrected) statement would be short for: template a(T) { alias a = b!(T, known_type); } That would be certainly very un-evil ;) -Steve
Mar 18 2011
prev sibling next sibling parent "Simen kjaeraas" <simen.kjaras gmail.com> writes:
On Fri, 18 Mar 2011 21:41:56 +0100, Steven Schveighoffer  
<schveiguy yahoo.com> wrote:

 On Fri, 18 Mar 2011 16:37:49 -0400, Andrei Alexandrescu  
 <SeeWebsiteForEmail erdani.org> wrote:

 On 3/18/11 3:28 PM, so wrote:
 alias a(T) = b(T, known_type);

 Would it be an overkill?

It's part of the evil plan.

(I think there is a typo above, shouldn't it be alias a(T) = b!(T, known_type) ? )

Could also be used for currying, I guess. void foo(int i, string s){} void foo(float f, string s){} alias bar(value) = foo(value, "Move along"); -- Simen
Mar 18 2011
prev sibling next sibling parent "Simen kjaeraas" <simen.kjaras gmail.com> writes:
On Fri, 18 Mar 2011 15:09:23 +0100, Nick Sabalausky <a a.a> wrote:

 "Bekenn" <leaveme alone.com> wrote in message
 news:ilv2pd$1vkd$1 digitalmars.com...
 On 3/17/2011 2:36 PM, Andrei Alexandrescu wrote:
 I'm with y'all too. Even Walter needs to stop and think for a second.
 We're considering enabling

 alias a = b;

 as an equivalent for

 alias b a;

Along similar lines (hoping this isn't too far off-topic), what's the current plan for typedef? I'm aware that it's deprecated (and for good reason), but some of my reading suggests that there's a successor on the horizon.

I was thinking of asking about that, too. Specifically, would it make sence for "typedef b a;" (or "typedef a = b;") to be lowered to something like: struct a { b _tmp; alias _tmp this; } Hmm, then again, IIUC, that would allow 'a' to be implicity converted to 'b' which would defeat half the point, so maybe not.

Yeah. Typedef is too blunt an instrument for our purposes. What we want is: alias Subtype!int SubInt; alias Supertype!int SupInt; alias Standalone!int NaturalNumber; Where the following work: int a = SubInt(3); SupInt b = 3; NaturalNumber c = NaturalNumber(3); and the following do not: SubInt d = 3; int e = SupInt(3); NaturalNumber f = 3; int g = NaturalNumber(3); And of course: alias Subtype!int SubInt2; alias Supertype!int SupInt2; alias Standalone!int NaturalNumber2; Where these do not work: SubInt2 h = SubInt(3); SupInt2 i = SupInt(3); NaturalNumber2 j = NaturalNumber(3); -- Simen
Mar 18 2011
prev sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Maybe

template addSize(...)
{
   enum this = ...;
}
Mar 19 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 15 Mar 2011 09:25:13 -0400, Jens <jne somewhere.org> wrote:

 It seems rather fundamental to be able to compose a new struct from a
 given struct using inheritance. Why is this not allowed?

 struct slist_node
 {
     slist_node* next;
 };

 template <class T>
 struct slist_node<T>: public slist_node
 {
     T data;
 };

struct slist_node { slist_node* next; } struct slist_node_t(T) { slist_node base; T data; alias base this; } should do the trick. But I would point out that you are better off not doing a s-list this way, since traversing will require much casting. -Steve
Mar 15 2011
prev sibling next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Tuesday 15 March 2011 06:25:13 Jens wrote:
 It seems rather fundamental to be able to compose a new struct from a
 given struct using inheritance. Why is this not allowed?
 
 struct slist_node
 {
     slist_node* next;
 };
 
 template <class T>
 struct slist_node<T>: public slist_node
 {
     T data;
 };

Classes are polymorphic. Structs are not. This is by design. One of the major reasons for this is slicing. In C++, if you have a pointer to an object, the pointer can be of a base type or of the same type as what is pointed to. You don't necessarily care. The correct code is called polymorphically. When you assign it to another pointer, it works just fine. You can even safely assign it to a pointer of a base type. class A {} class B : public A {} A* a = new B(); B* b = new B(); You can do the same in D with classes and references (and pointers, except that pointers aren't polymorphic in D). However, what happens if the type is on the stack directly? A a = *(new B()); B b = *(new B()); Your object just got sliced ( http://en.wikipedia.org/wiki/Object_slicing ). When it's on the stack, the compiler must know _exactly_ what type of object it is. That means that you can't have it be a different type than what you say it is. And that means that while assigning a B to a B works just fine, assigning a B to an A means that all the parts of that object that are B-specific, get lost. Only the parts that are part of an A get copied (since you just assigned it to an A). Take class A { int x; } class B : public A { int y; float z; } An A has an int in it. A B has an additional y and z in it. When you assign a B to an A, the y and z variables get lost. In many cases, this results in a completely invalid object and is _rarely_ what you really want. If you're not careful, this can be a big problem in C++. In C++, you _must_ use pointers if you want polymorphism. This also means that you generally avoid assigning dereferenced pointers to stack variables. D's solution is to make it so that there is a clear separation between non- polymorphic types on the stack and polymorphic types on the heap. Structs have no polymorphism and no inheritance. They live on th stack. Classes do have polymorphism nad ihneritance. They live on the heap. You _can_ have pointers to structs, but they're still non-polymorphic, and you can't normally stick a class on the stack. There are other benefits to making structs non-polymorphic (such as not needing a virtual table), but the main one is to avoid the slicing issue. Overall, it works quite well. One of the major, potential sources of bugs in C++ is completely avoided in D. - Jonathan M Davis
Mar 15 2011
parent reply "Jens" <jne somewhere.org> writes:
Jonathan M Davis wrote:
 On Tuesday 15 March 2011 06:25:13 Jens wrote:
 It seems rather fundamental to be able to compose a new struct from a
 given struct using inheritance. Why is this not allowed?

 struct slist_node
 {
     slist_node* next;
 };

 template <class T>
 struct slist_node<T>: public slist_node
 {
     T data;
 };

Classes are polymorphic. Structs are not.

OK, silly me. I used a wrong example. I really did want to know about non-polymorphic composition from structs via derivation. Sorry for the confusion. struct point { int x; int y; }; struct point3d: point { int z; };
Mar 15 2011
parent reply Jesse Phillips <jessekphillips+D gmail.com> writes:
Jens Wrote:

 OK, silly me. I used a wrong example. I really did want to know about 
 non-polymorphic composition from structs via derivation. Sorry for the 
 confusion.
 
 struct point
 {
     int x;
     int y;
 };
 
 struct point3d: point
 {
     int z;
 };

You already got your answer 'alias this' which you have dismissed as ugly. You wanted composition and I think it provides a very clean way to describe composition, especially since it looks nothing like how inheritance of classes which have polymorphic behavior. Also note the intent is to allow for multiple 'alias this' declarations, but hasn't yet been implemented. struct point { int x; int y; }; struct point3d { point p; // I own a point alias this p; // I am a composition of a point p. int z; };
Mar 15 2011
parent reply "Jens" <jne somewhere.org> writes:
Jesse Phillips wrote:
 Jens Wrote:

 OK, silly me. I used a wrong example. I really did want to know about
 non-polymorphic composition from structs via derivation. Sorry for
 the confusion.

 struct point
 {
     int x;
     int y;
 };

 struct point3d: point
 {
     int z;
 };

You already got your answer 'alias this' which you have dismissed as ugly. You wanted composition and I think it provides a very clean way to describe composition, especially since it looks nothing like how inheritance of classes which have polymorphic behavior.

Inheritance and polymorphic behavior can be (should be IMO) orthogonal.
 Also note the
 intent is to allow for multiple 'alias this' declarations, but hasn't
 yet been implemented.

 struct point
 {
     int x;
     int y;
 };

 struct point3d
 {
     point p; // I own a point
     alias this p;  // I am a composition of a point p.
     int z;
 };

I didn't ask how to do composition in D. I asked why composition cannot be done via derivation, i.e., the reasoning behind the language design choice. A design faux paus IMO.
Mar 15 2011
next sibling parent reply "Jens" <jne somewhere.org> writes:
Steven Schveighoffer wrote:
 On Tue, 15 Mar 2011 14:54:13 -0400, Jens <jne somewhere.org> wrote:

 I didn't ask how to do composition in D. I asked why composition
 cannot be done via derivation, i.e., the reasoning behind the
 language design choice. A design faux paus IMO.

Because composition by inheritance can be *completely* implemented using alias this -- a feature that also provides other niceties. Why provide another mechanism to do the exact same thing, just because you are used to it?

1. I'm not convinced the other functionality is necessary. 2. I eschew ugly syntax.
 Note that "inheritance" is actually done exactly this way in C++, by
 putting the derived type at the front of the "derived" type, and
 aliasing all the methods/fields into the derived namespace.

 Show me what composition by derivation provides that alias this does
 not.

Nice syntax.
Mar 15 2011
next sibling parent reply "Jens" <jne somewhere.org> writes:
Steven Schveighoffer wrote:
 On Tue, 15 Mar 2011 15:28:09 -0400, Jens <jne somewhere.org> wrote:

 Steven Schveighoffer wrote:
 On Tue, 15 Mar 2011 14:54:13 -0400, Jens <jne somewhere.org> wrote:

 I didn't ask how to do composition in D. I asked why composition
 cannot be done via derivation, i.e., the reasoning behind the
 language design choice. A design faux paus IMO.

Because composition by inheritance can be *completely* implemented using alias this -- a feature that also provides other niceties. Why provide another mechanism to do the exact same thing, just because you are used to it?

1. I'm not convinced the other functionality is necessary. 2. I eschew ugly syntax.

Beauty is subjective, so I guess I can say at this point, go write your own language that is beautiful in your mind. Good luck.

I am. Thanks.
 Note that "inheritance" is actually done exactly this way in C++, by
 putting the derived type at the front of the "derived" type, and
 aliasing all the methods/fields into the derived namespace.

 Show me what composition by derivation provides that alias this does
 not.

Nice syntax.

So in other words, you want an aqua-blue bikeshed, when D's is just blue. This will be my last reply to this thread...

Aww, little boy didn't get his way and is going home to cry to mommy.
Mar 15 2011
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 03/15/2011 12:42 PM, Jens wrote:
 Steven Schveighoffer wrote:
 Beauty is subjective, so I guess I can say at this point, go write
 your own language that is beautiful in your mind.  Good luck.

I am. Thanks.

You don't have what it takes to write a language yet. Beauty is only one aspect of languages. Picking features and calling them ugly is very easy. (I just did it quietly to myself; giggle, giggle.)
 Aww, little boy didn't get his way and is going home to cry to mommy.

Nobody here is trying get their way other than you. Most people will leave threads when it becomes obviously wasteful. I am going to my mommy too and I have a name! Ali
Mar 15 2011
parent reply "Jens" <jne somewhere.org> writes:
Ali Çehreli wrote:
 On 03/15/2011 12:42 PM, Jens wrote:
 Steven Schveighoffer wrote:
 Beauty is subjective, so I guess I can say at this point, go write
 your own language that is beautiful in your mind.  Good luck.

I am. Thanks.

You don't have what it takes to write a language yet.

You seem awfully sure about that, no? Are you omniscient? What is ironic is that someone from a D group is saying that. If I found D adequate, I wouldn't be developing another language, now would I? The prospect for D changing for the better don't look good.
 Beauty is only
 one aspect of languages.
 Picking features and calling them ugly is
 very easy. (I just did it quietly to myself; giggle, giggle.)

Sure, go ahead and dream up whatever fantasyland your mind requires.
 Aww, little boy didn't get his way and is going home to cry to mommy.

Nobody here is trying get their way other than you.

Contraire, obviously as evidenced, when someone walks in and is obviously not potential prey for the D propaganda machine, the ad hominem machine kicks in. M.O. noted.
 Most people will
 leave threads when it becomes obviously wasteful.

 I am going to my mommy too and I have a name!

Mar 15 2011
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 3/15/2011 3:41 PM, Andrej Mitrovic wrote:
 I'd say the primary reason someone won't land on a D page if it's the
 first time she's looking for it is because D is simply not that
 popular yet. But saying that it's not searchable because of its name
 is silly, imo.

D is very searchable if you search for "D programming language".
Mar 15 2011
parent reply Daniel Gibson <metalcaedes gmail.com> writes:
Am 15.03.2011 23:55, schrieb Walter Bright:
 On 3/15/2011 3:41 PM, Andrej Mitrovic wrote:
 I'd say the primary reason someone won't land on a D page if it's the
 first time she's looking for it is because D is simply not that
 popular yet. But saying that it's not searchable because of its name
 is silly, imo.

D is very searchable if you search for "D programming language".

That's fine if you want to find D's official homepage. But if you want to find a library for a specific purpose or something like that it's not that easy because you can't be sure that the author wrote exactly that on his homepage (and not just "my <something_useful> library for D"). So you end up looking ad Dsource, google code (even though they have a lot of projects flagged with "D" that have nothing to do with this language), sourceforce, ... Maybe you find nothing and later, by accident, stumble upon it on some private homepage.. I really wish you'd have named the language "mars" ;-) Cheers, - Daniel
Mar 15 2011
parent Walter Bright <newshound2 digitalmars.com> writes:
On 3/15/2011 4:04 PM, Daniel Gibson wrote:
 D is very searchable if you search for "D programming language".

That's fine if you want to find D's official homepage. But if you want to find a library for a specific purpose or something like that it's not that easy because you can't be sure that the author wrote exactly that on his homepage (and not just "my<something_useful> library for D"). So you end up looking ad Dsource, google code (even though they have a lot of projects flagged with "D" that have nothing to do with this language), sourceforce, ...

That's why I constantly nag people to have the phrase "D programming language" somewhere on their pages that concern D.
Mar 15 2011
prev sibling parent Ary Manzana <ary esperanto.org.ar> writes:
On 3/15/11 4:35 PM, Steven Schveighoffer wrote:
 On Tue, 15 Mar 2011 15:28:09 -0400, Jens <jne somewhere.org> wrote:

 Steven Schveighoffer wrote:
 On Tue, 15 Mar 2011 14:54:13 -0400, Jens <jne somewhere.org> wrote:

 I didn't ask how to do composition in D. I asked why composition
 cannot be done via derivation, i.e., the reasoning behind the
 language design choice. A design faux paus IMO.

Because composition by inheritance can be *completely* implemented using alias this -- a feature that also provides other niceties. Why provide another mechanism to do the exact same thing, just because you are used to it?

1. I'm not convinced the other functionality is necessary. 2. I eschew ugly syntax.

Beauty is subjective, so I guess I can say at this point, go write your own language that is beautiful in your mind. Good luck.

Beauty is not that all subjective. http://www.youtube.com/watch?v=PktUzdnBqWI See my previous post. Which one you find more ugly?
Mar 16 2011
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 3/15/11 1:54 PM, Jens wrote:
 Jesse Phillips wrote:
 Jens Wrote:

 OK, silly me. I used a wrong example. I really did want to know about
 non-polymorphic composition from structs via derivation. Sorry for
 the confusion.

 struct point
 {
      int x;
      int y;
 };

 struct point3d: point
 {
      int z;
 };

You already got your answer 'alias this' which you have dismissed as ugly. You wanted composition and I think it provides a very clean way to describe composition, especially since it looks nothing like how inheritance of classes which have polymorphic behavior.

Inheritance and polymorphic behavior can be (should be IMO) orthogonal.

In concept it's easy to abide to strong stances, and I wouldn't disagree it's not half a bad thing. However, real-world issues do arise. Inheritance is often a desirable mechanism for implementing dynamic polymorphism for two main reasons. One, it prevents accidental polymorphism from happening. Two, it allows the compiler to lay out objects efficiently and make function invocation relatively fast without a need for global information. Offhand I don't think there are other reasons. Inheritance without polymorphism is technically possible, but rarely of any practical interest. In C++, next to nobody uses private inheritance systematically, and nobody really understands what protected inheritance really is. Polymorphism without inheritance is the election mechanism during compilation, and possible for runtime polymorphism with well-understood reflection mechanisms (btw I see now that adaptTo has not been yet added to std.typecons...) All in all inheritance is strongly associated with polymorphism as it is a basic mechanism for implementing it, so it would be tenuous to force the two to be orthogonal.
 Also note the
 intent is to allow for multiple 'alias this' declarations, but hasn't
 yet been implemented.

 struct point
 {
      int x;
      int y;
 };

 struct point3d
 {
      point p; // I own a point
      alias this p;  // I am a composition of a point p.
      int z;
 };

I didn't ask how to do composition in D. I asked why composition cannot be done via derivation, i.e., the reasoning behind the language design choice. A design faux paus IMO.

I would agree, with the slight amendment that this time for once the faux pas is in the design of the application, not that of the language. Andrei
Mar 15 2011
parent reply "Jens" <jne somewhere.org> writes:
Andrei Alexandrescu wrote:
 On 3/15/11 1:54 PM, Jens wrote:
 Jesse Phillips wrote:
 Jens Wrote:

 OK, silly me. I used a wrong example. I really did want to know
 about non-polymorphic composition from structs via derivation.
 Sorry for the confusion.

 struct point
 {
      int x;
      int y;
 };

 struct point3d: point
 {
      int z;
 };

You already got your answer 'alias this' which you have dismissed as ugly. You wanted composition and I think it provides a very clean way to describe composition, especially since it looks nothing like how inheritance of classes which have polymorphic behavior.

Inheritance and polymorphic behavior can be (should be IMO) orthogonal.

In concept it's easy to abide to strong stances, and I wouldn't disagree it's not half a bad thing. However, real-world issues do arise.

And all those xxx-ability words apply. Such as useability, comprehensibility, learnability.. etc. There is technical "correctness" and then there is "the good thing".
 Inheritance is often a desirable mechanism for implementing dynamic
 polymorphism for two main reasons. One, it prevents accidental
 polymorphism from happening. Two, it allows the compiler to lay out
 objects efficiently and make function invocation relatively fast
 without a need for global information. Offhand I don't think there
 are other reasons.

 Inheritance without polymorphism is technically possible, but rarely
 of any practical interest.

Yeah, jettison clean syntax because it's of little importance. :/
 In C++, next to nobody uses private
 inheritance systematically, and nobody really understands what
 protected inheritance really is.

I avoid private inheritance and never used protected inheritance. I use composition in those cases but that is when B. Meyer's books come of the shelf for a reread. I was originally talking just about structural extension (I probably said "composition" but "extension" is a tad better term) via inheritance syntax. "inheritance" isn't the key thought in all of that. "extension" and "syntax" are.
 Polymorphism without inheritance is the election mechanism during
 compilation, and possible for runtime polymorphism with
 well-understood reflection mechanisms (btw I see now that adaptTo has
 not been yet added to std.typecons...)

 All in all inheritance is strongly associated with polymorphism as it
 is a basic mechanism for implementing it, so it would be tenuous to
 force the two to be orthogonal.

"orthogonal" is a bit strong, but I left it in. Let's face it, when you derive, you get data members and methods. In a struct with no methods, you get data members only, in a nice clean way. I find that compelling, syntax-wise.
 Also note the
 intent is to allow for multiple 'alias this' declarations, but
 hasn't yet been implemented.

 struct point
 {
      int x;
      int y;
 };

 struct point3d
 {
      point p; // I own a point
      alias this p;  // I am a composition of a point p.
      int z;
 };

I didn't ask how to do composition in D. I asked why composition cannot be done via derivation, i.e., the reasoning behind the language design choice. A design faux paus IMO.

I would agree, with the slight amendment that this time for once the faux pas is in the design of the application, not that of the language.

We'll have to agree to disagree on this one then. I'm sure there will be others. ;)
Mar 15 2011
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 3/15/11 2:55 PM, Jens wrote:
 We'll have to agree to disagree on this one then. I'm sure there will be
 others. ;)

I hope this newsgroup will use future opportunities for learning from you. It would never hurt if you did the converse (this is really not the place and the entourage to be cocky), to say nothing about being courteous to the other participants. Thanks, Andrei
Mar 15 2011
parent reply "Jens" <jne somewhere.org> writes:
Andrei Alexandrescu wrote:
 On 3/15/11 2:55 PM, Jens wrote:
 We'll have to agree to disagree on this one then. I'm sure there
 will be others. ;)

I hope this newsgroup will use future opportunities for learning from you. It would never hurt if you did the converse (this is really not the place and the entourage to be cocky), to say nothing about being courteous to the other participants.

I wasn't being. I know what I want in a language. I'm also tough, thick-skinned, non-patronizing, non-sheeplish... Don't take it personally. If someone is wimpy, they probably shouldn't be dialogue-ing with me. It's technology for pete's sake. (Aside: Anyone know who pete is?).
Mar 15 2011
next sibling parent reply David Nadlinger <see klickverbot.at> writes:
On 3/15/11 9:24 PM, Jens wrote:
 Andrei Alexandrescu wrote:
 On 3/15/11 2:55 PM, Jens wrote:
 We'll have to agree to disagree on this one then. I'm sure there
 will be others. ;)

I hope this newsgroup will use future opportunities for learning from you. It would never hurt if you did the converse (this is really not the place and the entourage to be cocky), to say nothing about being courteous to the other participants.

I wasn't being. I know what I want in a language. I'm also tough, thick-skinned, non-patronizing, non-sheeplish... Don't take it personally. If someone is wimpy, they probably shouldn't be dialogue-ing with me. It's technology for pete's sake.

http://en.wikipedia.org/wiki/Netiquette
Mar 15 2011
parent "Nick Sabalausky" <a a.a> writes:
"David Nadlinger" <see klickverbot.at> wrote in message 
news:iloidv$8s1$1 digitalmars.com...
 On 3/15/11 9:24 PM, Jens wrote:
 Andrei Alexandrescu wrote:
 On 3/15/11 2:55 PM, Jens wrote:
 We'll have to agree to disagree on this one then. I'm sure there
 will be others. ;)

I hope this newsgroup will use future opportunities for learning from you. It would never hurt if you did the converse (this is really not the place and the entourage to be cocky), to say nothing about being courteous to the other participants.

I wasn't being. I know what I want in a language. I'm also tough, thick-skinned, non-patronizing, non-sheeplish... Don't take it personally. If someone is wimpy, they probably shouldn't be dialogue-ing with me. It's technology for pete's sake.

http://en.wikipedia.org/wiki/Netiquette

http://en.wikipedia.org/wiki/Troll_(Internet)
Mar 15 2011
prev sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Jens:

 I wasn't being. I know what I want in a language. I'm also tough, 
 thick-skinned, non-patronizing, non-sheeplish... Don't take it 
 personally. If someone is wimpy, they probably shouldn't be dialogue-ing 
 with me. It's technology for pete's sake.

If you act like a decent human being more people will want to talk with you. Your answer to Steven Schveighoffer was bad, it damages the good mood of this community (and guess who is the true boy). Bye, bearophile
Mar 15 2011
parent reply "Jens" <jne somewhere.org> writes:
bearophile wrote:
 Jens:

 I wasn't being. I know what I want in a language. I'm also tough,
 thick-skinned, non-patronizing, non-sheeplish... Don't take it
 personally. If someone is wimpy, they probably shouldn't be
 dialogue-ing with me. It's technology for pete's sake.

If you act like a decent human being more people will want to talk with you. Your answer to Steven Schveighoffer was bad, it damages the good mood of this community (and guess who is the true boy). Bye, bearophile

He plonks when he doesn't get his way, I call him a baby. Plain and simple. I don't have time for childish newsgroup antics or characters.
Mar 15 2011
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 03/15/2011 04:04 PM, Simen kjaeraas wrote:
 Jens <jne somewhere.org> wrote:

 bearophile wrote:
 Jens:

 I wasn't being. I know what I want in a language. I'm also tough,
 thick-skinned, non-patronizing, non-sheeplish... Don't take it
 personally. If someone is wimpy, they probably shouldn't be
 dialogue-ing with me. It's technology for pete's sake.

If you act like a decent human being more people will want to talk with you. Your answer to Steven Schveighoffer was bad, it damages the good mood of this community (and guess who is the true boy). Bye, bearophile

He plonks when he doesn't get his way, I call him a baby. Plain and simple. I don't have time for childish newsgroup antics or characters.

Nor do we. Exit's over there.

Give the man (well possibly boy) a few days. He may turn around. (Other than that... post o' the day.) Andrei
Mar 15 2011
parent reply "Jens" <jne somewhere.org> writes:
Andrei Alexandrescu wrote:
 On 03/15/2011 04:04 PM, Simen kjaeraas wrote:
 Jens <jne somewhere.org> wrote:

 bearophile wrote:
 Jens:

 I wasn't being. I know what I want in a language. I'm also tough,
 thick-skinned, non-patronizing, non-sheeplish... Don't take it
 personally. If someone is wimpy, they probably shouldn't be
 dialogue-ing with me. It's technology for pete's sake.

If you act like a decent human being more people will want to talk with you. Your answer to Steven Schveighoffer was bad, it damages the good mood of this community (and guess who is the true boy). Bye, bearophile

He plonks when he doesn't get his way, I call him a baby. Plain and simple. I don't have time for childish newsgroup antics or characters.

Nor do we. Exit's over there.

Give the man (well possibly boy) a few days. He may turn around. (Other than that... post o' the day.) Andrei

Buh-bye children. You've convinced me: D is not for me.
Mar 15 2011
parent "Nick Sabalausky" <a a.a> writes:
"Jens" <jne somewhere.org> wrote in message 
news:ilon8h$lhu$1 digitalmars.com...
 Andrei Alexandrescu wrote:
 On 03/15/2011 04:04 PM, Simen kjaeraas wrote:
 Jens <jne somewhere.org> wrote:

 bearophile wrote:
 Jens:

 I wasn't being. I know what I want in a language. I'm also tough,
 thick-skinned, non-patronizing, non-sheeplish... Don't take it
 personally. If someone is wimpy, they probably shouldn't be
 dialogue-ing with me. It's technology for pete's sake.

If you act like a decent human being more people will want to talk with you. Your answer to Steven Schveighoffer was bad, it damages the good mood of this community (and guess who is the true boy). Bye, bearophile

He plonks when he doesn't get his way, I call him a baby. Plain and simple. I don't have time for childish newsgroup antics or characters.

Nor do we. Exit's over there.

Give the man (well possibly boy) a few days. He may turn around. (Other than that... post o' the day.) Andrei

Buh-bye children. You've convinced me: D is not for me.

Thank god.
Mar 15 2011
prev sibling parent reply Ary Manzana <ary esperanto.org.ar> writes:
On 3/15/11 4:06 PM, Steven Schveighoffer wrote:
 On Tue, 15 Mar 2011 14:54:13 -0400, Jens <jne somewhere.org> wrote:

 I didn't ask how to do composition in D. I asked why composition cannot
 be done via derivation, i.e., the reasoning behind the language design
 choice. A design faux paus IMO.

Because composition by inheritance can be *completely* implemented using alias this -- a feature that also provides other niceties. Why provide another mechanism to do the exact same thing, just because you are used to it? Note that "inheritance" is actually done exactly this way in C++, by putting the derived type at the front of the "derived" type, and aliasing all the methods/fields into the derived namespace. Show me what composition by derivation provides that alias this does not. -Steve

Oh, come on, why use alias this when you can implement it in assembler?
Mar 16 2011
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 03/16/2011 10:28 AM, Steven Schveighoffer wrote:
 On Wed, 16 Mar 2011 11:06:40 -0400, Ary Manzana <ary esperanto.org.ar>
 wrote:

 On 3/15/11 4:06 PM, Steven Schveighoffer wrote:
 On Tue, 15 Mar 2011 14:54:13 -0400, Jens <jne somewhere.org> wrote:

 I didn't ask how to do composition in D. I asked why composition cannot
 be done via derivation, i.e., the reasoning behind the language design
 choice. A design faux paus IMO.

Because composition by inheritance can be *completely* implemented using alias this -- a feature that also provides other niceties. Why provide another mechanism to do the exact same thing, just because you are used to it? Note that "inheritance" is actually done exactly this way in C++, by putting the derived type at the front of the "derived" type, and aliasing all the methods/fields into the derived namespace. Show me what composition by derivation provides that alias this does not.

Oh, come on, why use alias this when you can implement it in assembler?

There is a huge difference. We don't use the same syntax for polymorphic inheritance for struct inheritance because we do not want to confuse the developer. Essentially, the syntax looks better, but it looks exactly like polymorphic class/interface inheritance. The two types of extension are drastically different, and I think the syntax should reflect that. Besides, we are not talking the difference between assembler and high-level code here. We're talking the difference between X : Y and X { Y y; alias y this;} -Steve

Not to mention that alias this offers the ability of a runtime hook; you don't need structural conformance as you can produce the conversion on the fly. Andrei
Mar 16 2011
prev sibling next sibling parent Caligo <iteronvexor gmail.com> writes:
--20cf3071cbd8d2adcd049e87e933
Content-Type: text/plain; charset=ISO-8859-1

On Tue, Mar 15, 2011 at 10:00 AM, Jonathan M Davis <jmdavisProg gmx.com>wrote:

 On Tuesday 15 March 2011 06:25:13 Jens wrote:
 It seems rather fundamental to be able to compose a new struct from a
 given struct using inheritance. Why is this not allowed?

 struct slist_node
 {
     slist_node* next;
 };

 template <class T>
 struct slist_node<T>: public slist_node
 {
     T data;
 };

Classes are polymorphic. Structs are not. This is by design. One of the major reasons for this is slicing. In C++, if you have a pointer to an object, the pointer can be of a base type or of the same type as what is pointed to. You don't necessarily care. The correct code is called polymorphically. When you assign it to another pointer, it works just fine. You can even safely assign it to a pointer of a base type. class A {} class B : public A {} A* a = new B(); B* b = new B(); You can do the same in D with classes and references (and pointers, except that pointers aren't polymorphic in D). However, what happens if the type is on the stack directly? A a = *(new B()); B b = *(new B()); Your object just got sliced ( http://en.wikipedia.org/wiki/Object_slicing). When it's on the stack, the compiler must know _exactly_ what type of object it is. That means that you can't have it be a different type than what you say it is. And that means that while assigning a B to a B works just fine, assigning a B to an A means that all the parts of that object that are B-specific, get lost. Only the parts that are part of an A get copied (since you just assigned it to an A). Take class A { int x; } class B : public A { int y; float z; } An A has an int in it. A B has an additional y and z in it. When you assign a B to an A, the y and z variables get lost. In many cases, this results in a completely invalid object and is _rarely_ what you really want. If you're not careful, this can be a big problem in C++. In C++, you _must_ use pointers if you want polymorphism. This also means that you generally avoid assigning dereferenced pointers to stack variables. D's solution is to make it so that there is a clear separation between non- polymorphic types on the stack and polymorphic types on the heap. Structs have no polymorphism and no inheritance. They live on th stack. Classes do have polymorphism nad ihneritance. They live on the heap. You _can_ have pointers to structs, but they're still non-polymorphic, and you can't normally stick a class on the stack. There are other benefits to making structs non-polymorphic (such as not needing a virtual table), but the main one is to avoid the slicing issue. Overall, it works quite well. One of the major, potential sources of bugs in C++ is completely avoided in D. - Jonathan M Davis

struct MyStruct{ MyClass mc; // 4 bytes int a; int b; char c; } class MyClass{ MyStruct ms; // 16 bytes int x; int y; char z; } so, 'ms' is on the heap, even though it's a struct, right? but 'mc' is just a reference and lives on the stack, and that's why it's only 4 bytes? btw, coming from C++, I find 'MyClass mc;' and 'MyStruct ms;' confusing; one is a reference and the other isn't. --20cf3071cbd8d2adcd049e87e933 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable <br><br><div class=3D"gmail_quote">On Tue, Mar 15, 2011 at 10:00 AM, Jonath= an M Davis <span dir=3D"ltr">&lt;<a href=3D"mailto:jmdavisProg gmx.com">jmd= avisProg gmx.com</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote"= style=3D"margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 2= 04); padding-left: 1ex;"> <div><div></div><div class=3D"h5">On Tuesday 15 March 2011 06:25:13 Jens wr= ote:<br> &gt; It seems rather fundamental to be able to compose a new struct from a<= br> &gt; given struct using inheritance. Why is this not allowed?<br> &gt;<br> &gt; struct slist_node<br> &gt; {<br> &gt; =A0 =A0 slist_node* next;<br> &gt; };<br> &gt;<br> &gt; template &lt;class T&gt;<br> &gt; struct slist_node&lt;T&gt;: public slist_node<br> &gt; {<br> &gt; =A0 =A0 T data;<br> &gt; };<br> <br> </div></div>Classes are polymorphic. Structs are not. This is by design. On= e of the major<br> reasons for this is slicing. In C++, if you have a pointer to an object, th= e<br> pointer can be of a base type or of the same type as what is pointed to. Yo= u<br> don&#39;t necessarily care. The correct code is called polymorphically. Whe= n you<br> assign it to another pointer, it works just fine. You can even safely assig= n it<br> to a pointer of a base type.<br> <br> class A {}<br> class B : public A {}<br> <br> A* a =3D new B();<br> B* b =3D new B();<br> <br> You can do the same in D with classes and references (and pointers, except = that<br> pointers aren&#39;t polymorphic in D). However, what happens if the type is= on the<br> stack directly?<br> <br> A a =3D *(new B());<br> B b =3D *(new B());<br> <br> Your object just got sliced ( <a href=3D"http://en.wikipedia.org/wiki/Objec= t_slicing" target=3D"_blank">http://en.wikipedia.org/wiki/Object_slicing</a=
 ).<br>

bject it<br> is. That means that you can&#39;t have it be a different type than what you= say it<br> is. And that means that while assigning a B to a B works just fine, assigni= ng a B<br> to an A means that all the parts of that object that are B-specific, get lo= st.<br> Only the parts that are part of an A get copied (since you just assigned it= to<br> an A). Take<br> <br> class A<br> {<br> =A0 =A0int x;<br> }<br> <br> class B : public A<br> {<br> =A0 =A0int y;<br> =A0 =A0float z;<br> }<br> <br> An A has an int in it. A B has an additional y and z in it. When you assign= a B<br> to an A, the y and z variables get lost. In many cases, this results in a<b= r> completely invalid object and is _rarely_ what you really want. If you&#39;= re not<br> careful, this can be a big problem in C++. In C++, you _must_ use pointers = if<br> you want polymorphism. This also means that you generally avoid assigning<b= r> dereferenced pointers to stack variables.<br> <br> D&#39;s solution is to make it so that there is a clear separation between = non-<br> polymorphic types on the stack and polymorphic types on the heap. Structs h= ave<br> no polymorphism and no inheritance. They live on th stack. Classes do have<= br> polymorphism nad ihneritance. They live on the heap. You _can_ have pointer= s to<br> structs, but they&#39;re still non-polymorphic, and you can&#39;t normally = stick a class<br> on the stack.<br> <br> There are other benefits to making structs non-polymorphic (such as not nee= ding a<br> virtual table), but the main one is to avoid the slicing issue. Overall, it= <br> works quite well. One of the major, potential sources of bugs in C++ is<br> completely avoided in D.<br> <font color=3D"#888888"><br> - Jonathan M Davis<br> </font></blockquote></div><br><br><br>struct MyStruct{<br><br>=A0 MyClass m= c;=A0 // 4 bytes<br>=A0 int a;<br>=A0 int b;<br>=A0 char c;<br>}<br><br>cla= ss MyClass{<br><br>=A0 MyStruct ms;=A0 // 16 bytes<br>=A0 int x;<br>=A0 int= y;<br>=A0 char z;<br> }<br><br><br>so, &#39;ms&#39; is on the heap, even though it&#39;s a struct= , right?=A0 but &#39;mc&#39; is just a reference and lives on the stack, an= d that&#39;s why it&#39;s only 4 bytes?<br><br>btw, coming from C++, I find= &#39;MyClass mc;&#39; and &#39;MyStruct ms;&#39; confusing; one is a refer= ence and the other isn&#39;t.=A0 <br> --20cf3071cbd8d2adcd049e87e933--
Mar 15 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 15 Mar 2011 12:28:07 -0400, Caligo <iteronvexor gmail.com> wrote:

 struct MyStruct{

   MyClass mc;  // 4 bytes
   int a;
   int b;
   char c;
 }

 class MyClass{

   MyStruct ms;  // 16 bytes
   int x;
   int y;
   char z;
 }


 so, 'ms' is on the heap, even though it's a struct, right?  but 'mc' is  
 just
 a reference and lives on the stack, and that's why it's only 4 bytes?

 btw, coming from C++, I find 'MyClass mc;' and 'MyStruct ms;' confusing;  
 one
 is a reference and the other isn't.

Yes, it's not struct vs. heap more than it is value semantics vs. reference semantics. A class is *always* pass-by-reference, and must be initialized with a constructor. A struct is allocated where it is declared (on the stack, in a class or struct, etc.), and is typically pass-by-value. What Jonathan was saying is that classes naturally go on the heap, because that's what makes the most sense for reference semantics. Structs naturally go wherever you declare them, which can be on the stack. A struct can also have reference semantics if it is a pImpl type struct (such as an associative array). The point of making these distinctions is that polymorphism *requires* reference semantics. You can't use a virtual function without a reference. If you do, it is not a virtual call. This is why only classes which implement strictly reference semantics can have polymorphism in D. -Steve
Mar 15 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 15 Mar 2011 13:24:27 -0400, Steven Schveighoffer  
<schveiguy yahoo.com> wrote:

 Yes, it's not struct vs. heap more than it is value semantics vs. ...

That should have said "stack vs. heap". -Steve
Mar 15 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 15 Mar 2011 14:54:13 -0400, Jens <jne somewhere.org> wrote:

 I didn't ask how to do composition in D. I asked why composition cannot
 be done via derivation, i.e., the reasoning behind the language design
 choice. A design faux paus IMO.

Because composition by inheritance can be *completely* implemented using alias this -- a feature that also provides other niceties. Why provide another mechanism to do the exact same thing, just because you are used to it? Note that "inheritance" is actually done exactly this way in C++, by putting the derived type at the front of the "derived" type, and aliasing all the methods/fields into the derived namespace. Show me what composition by derivation provides that alias this does not. -Steve
Mar 15 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 15 Mar 2011 15:28:09 -0400, Jens <jne somewhere.org> wrote:

 Steven Schveighoffer wrote:
 On Tue, 15 Mar 2011 14:54:13 -0400, Jens <jne somewhere.org> wrote:

 I didn't ask how to do composition in D. I asked why composition
 cannot be done via derivation, i.e., the reasoning behind the
 language design choice. A design faux paus IMO.

Because composition by inheritance can be *completely* implemented using alias this -- a feature that also provides other niceties. Why provide another mechanism to do the exact same thing, just because you are used to it?

1. I'm not convinced the other functionality is necessary. 2. I eschew ugly syntax.

Beauty is subjective, so I guess I can say at this point, go write your own language that is beautiful in your mind. Good luck.
 Note that "inheritance" is actually done exactly this way in C++, by
 putting the derived type at the front of the "derived" type, and
 aliasing all the methods/fields into the derived namespace.

 Show me what composition by derivation provides that alias this does
 not.

Nice syntax.

So in other words, you want an aqua-blue bikeshed, when D's is just blue. This will be my last reply to this thread... -Steve
Mar 15 2011
prev sibling next sibling parent "Simen kjaeraas" <simen.kjaras gmail.com> writes:
Jens <jne somewhere.org> wrote:

 bearophile wrote:
 Jens:

 I wasn't being. I know what I want in a language. I'm also tough,
 thick-skinned, non-patronizing, non-sheeplish... Don't take it
 personally. If someone is wimpy, they probably shouldn't be
 dialogue-ing with me. It's technology for pete's sake.

If you act like a decent human being more people will want to talk with you. Your answer to Steven Schveighoffer was bad, it damages the good mood of this community (and guess who is the true boy). Bye, bearophile

He plonks when he doesn't get his way, I call him a baby. Plain and simple. I don't have time for childish newsgroup antics or characters.

Nor do we. Exit's over there. -- Simen
Mar 15 2011
prev sibling next sibling parent Caligo <iteronvexor gmail.com> writes:
--20cf307d02ca80803f049e8d0a35
Content-Type: text/plain; charset=ISO-8859-1

On Tue, Mar 15, 2011 at 4:03 PM, Jens <jne somewhere.org> wrote:

  If I found D adequate, I wouldn't be developing another language, now
 would I?

I suggest D++? --20cf307d02ca80803f049e8d0a35 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable <br><br><div class=3D"gmail_quote">On Tue, Mar 15, 2011 at 4:03 PM, Jens <s= pan dir=3D"ltr">&lt;<a href=3D"mailto:jne somewhere.org">jne somewhere.org<= /a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:= 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left= : 1ex;"> <div class=3D"im"> <br> </div> If I found D adequate, I wouldn&#39;t be developing another language, now would I? <br><div><div cla= ss=3D"h5"> <br> <br> </div></div></blockquote></div><br>Have you come up with a name for this la= nguage that you are developing?=A0 May I suggest D++?<br> --20cf307d02ca80803f049e8d0a35--
Mar 15 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 3/15/11, Caligo <iteronvexor gmail.com> wrote:
 Have you come up with a name for this language that you are developing?  May
 I suggest D++?

Speaking of language names.. I never understood why people whine about "D not being searchable because of its name". Then how is `C` searchable? Heck, half of the results when searching for C will land you C++ results. And searching just for `C` isn't going to give you good results in the first place unless Google has some of your previous searches stored and figures out you're looking for the programming language and not something else. I'd say the primary reason someone won't land on a D page if it's the first time she's looking for it is because D is simply not that popular yet. But saying that it's not searchable because of its name is silly, imo.
Mar 15 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 3/15/11, Walter Bright <newshound2 digitalmars.com> wrote:
 On 3/15/2011 3:41 PM, Andrej Mitrovic wrote:
 I'd say the primary reason someone won't land on a D page if it's the
 first time she's looking for it is because D is simply not that
 popular yet. But saying that it's not searchable because of its name
 is silly, imo.

D is very searchable if you search for "D programming language".

Another search engine like duckduckgo even figures out you might be looking for D: https://duckduckgo.com/?q=D It's right there under 'Computing'. If you hit it you get a whole bunch of results specific to the language. In fact the next time someone complains about it not being searchable, just redirect them to this page: https://duckduckgo.com/D_%28programming_language%29 ;)
Mar 15 2011
prev sibling next sibling parent Caligo <iteronvexor gmail.com> writes:
--bcaec501c5c027de7b049e8d71f3
Content-Type: text/plain; charset=ISO-8859-1

On Tue, Mar 15, 2011 at 5:41 PM, Andrej Mitrovic <andrej.mitrovich gmail.com
 wrote:

 Speaking of language names.. I never understood why people whine about
 "D not being searchable because of its name". Then how is `C`
 searchable? Heck, half of the results when searching for C will land
 you C++ results. And searching just for `C` isn't going to give you
 good results in the first place unless Google has some of your
 previous searches stored and figures out you're looking for the
 programming language and not something else.

 I'd say the primary reason someone won't land on a D page if it's the
 first time she's looking for it is because D is simply not that
 popular yet. But saying that it's not searchable because of its name
 is silly, imo.

Interesting your brought that up. Here is Google search results: C programming language == About 18,200,000 results C++ programming language == About 6,030,000 results D programming language == About 5,950,000 results java programming language == About 9,130,000 results python programming language == About 3,720,000 results ruby programming language == About 354,000 results go programming language == About 12,700,000 results and here are the exact search results: "C programming language" == About 902,000 results "C++ programming language" == About 371,000 results "D programming language" == About 75,800 results "java programming language" == About 1,250,000 results "python programming language" == About 238,000 results "ruby programming language" == About 132,000 results "go programming language" == About 116,000 results --bcaec501c5c027de7b049e8d71f3 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable <br><br><div class=3D"gmail_quote">On Tue, Mar 15, 2011 at 5:41 PM, Andrej = Mitrovic <span dir=3D"ltr">&lt;<a href=3D"mailto:andrej.mitrovich gmail.com= ">andrej.mitrovich gmail.com</a>&gt;</span> wrote:<br><blockquote class=3D"= gmail_quote" style=3D"margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb= (204, 204, 204); padding-left: 1ex;"> <div class=3D"im"> <br> </div>Speaking of language names.. I never understood why people whine abou= t<br> &quot;D not being searchable because of its name&quot;. Then how is `C`<br> searchable? Heck, half of the results when searching for C will land<br> you C++ results. And searching just for `C` isn&#39;t going to give you<br> good results in the first place unless Google has some of your<br> previous searches stored and figures out you&#39;re looking for the<br> programming language and not something else.<br> <br> I&#39;d say the primary reason someone won&#39;t land on a D page if it&#39= ;s the<br> first time she&#39;s looking for it is because D is simply not that<br> popular yet. But saying that it&#39;s not searchable because of its name<br=

</blockquote></div><br><br>Interesting your brought that up.=A0 Here is Goo= gle search results:<br><br>C programming language=A0=A0=A0=A0=A0 =3D=3D=A0 = About 18,200,000 results<br>C++ programming language=A0=A0=A0 =3D=3D=A0 Abo= ut 6,030,000 results<br>D programming language=A0=A0=A0=A0=A0 =3D=3D=A0 Abo= ut 5,950,000 results<br> java programming language=A0=A0 =3D=3D=A0 About 9,130,000 results<br>python= programming language =3D=3D=A0 About 3,720,000 results<br>ruby programming= language=A0=A0 =3D=3D=A0 About 354,000 results<br>go programming language= =A0=A0=A0=A0 =3D=3D=A0 About 12,700,000 results<br> <br><br>and here are the exact search results:<br><br>&quot;C programming l= anguage&quot;=A0=A0=A0=A0=A0 =3D=3D=A0 About 902,000 results<br>&quot;C++ p= rogramming language&quot;=A0=A0=A0 =3D=3D=A0 About 371,000 results<br>&quot= ;D programming language&quot;=A0=A0=A0=A0=A0 =3D=3D=A0 About 75,800 results= <br> &quot;java programming language&quot;=A0=A0 =3D=3D=A0 About 1,250,000 resul= ts<br>&quot;python programming language&quot; =3D=3D=A0 About 238,000 resul= ts<br>&quot;ruby programming language&quot;=A0=A0 =3D=3D=A0 About 132,000 r= esults<br>&quot;go programming language&quot;=A0=A0=A0=A0 =3D=3D=A0 About 1= 16,000 results <br> --bcaec501c5c027de7b049e8d71f3--
Mar 15 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 3/15/11, dsimcha <dsimcha yahoo.com> wrote:
 Something that has basically that effect is allowed, just not with that
 syntax:

 struct slist_node(T)
 {
      slist_node base;
      alias base this;

      T data;
 }

Shouldn't base be a pointer? You'll get errors with that code.
Mar 15 2011
prev sibling next sibling parent "Regan Heath" <regan netmail.co.nz> writes:
On Tue, 15 Mar 2011 19:42:20 -0000, Jens <jne somewhere.org> wrote:

 Steven Schveighoffer wrote:
 On Tue, 15 Mar 2011 15:28:09 -0400, Jens <jne somewhere.org> wrote:

 Steven Schveighoffer wrote:
 On Tue, 15 Mar 2011 14:54:13 -0400, Jens <jne somewhere.org> wrote:

 I didn't ask how to do composition in D. I asked why composition
 cannot be done via derivation, i.e., the reasoning behind the
 language design choice. A design faux paus IMO.

Because composition by inheritance can be *completely* implemented using alias this -- a feature that also provides other niceties. Why provide another mechanism to do the exact same thing, just because you are used to it?

1. I'm not convinced the other functionality is necessary. 2. I eschew ugly syntax.

Beauty is subjective, so I guess I can say at this point, go write your own language that is beautiful in your mind. Good luck.

I am. Thanks.
 Note that "inheritance" is actually done exactly this way in C++, by
 putting the derived type at the front of the "derived" type, and
 aliasing all the methods/fields into the derived namespace.

 Show me what composition by derivation provides that alias this does
 not.

Nice syntax.

So in other words, you want an aqua-blue bikeshed, when D's is just blue. This will be my last reply to this thread...

Aww, little boy didn't get his way and is going home to cry to mommy.

Grow up. Steven has done the adult thing and realised your difference of opinion is based solely on personal preference, and therefore any argument on his part is futile. You, on the other hand, have resorted to personal attacks.. a logical fallacy which typically means lack of self control and/or no valid rebuttal to the actual argument. Way to go. -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Mar 16 2011
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Wed, 16 Mar 2011 11:06:40 -0400, Ary Manzana <ary esperanto.org.ar>  
wrote:

 On 3/15/11 4:06 PM, Steven Schveighoffer wrote:
 On Tue, 15 Mar 2011 14:54:13 -0400, Jens <jne somewhere.org> wrote:

 I didn't ask how to do composition in D. I asked why composition cannot
 be done via derivation, i.e., the reasoning behind the language design
 choice. A design faux paus IMO.

Because composition by inheritance can be *completely* implemented using alias this -- a feature that also provides other niceties. Why provide another mechanism to do the exact same thing, just because you are used to it? Note that "inheritance" is actually done exactly this way in C++, by putting the derived type at the front of the "derived" type, and aliasing all the methods/fields into the derived namespace. Show me what composition by derivation provides that alias this does not.

Oh, come on, why use alias this when you can implement it in assembler?

There is a huge difference. We don't use the same syntax for polymorphic inheritance for struct inheritance because we do not want to confuse the developer. Essentially, the syntax looks better, but it looks exactly like polymorphic class/interface inheritance. The two types of extension are drastically different, and I think the syntax should reflect that. Besides, we are not talking the difference between assembler and high-level code here. We're talking the difference between X : Y and X { Y y; alias y this;} -Steve
Mar 16 2011