digitalmars.D - Improvement to struct inheritance possible?
- Danilo (68/68) Jan 17 The following code does not work, and I think it may be a bug or
- zjh (6/10) Jan 17 Why can't struct be inherited ?C++ has good `struct inheritance`,
- zjh (7/13) Jan 17 I look forward to `someone` writing a `compiler plugin` that can
- Steven Schveighoffer (10/47) Jan 18 Just FYI, it's kind of a special case that `typeof(this)` works
- Meta (13/81) Jan 18 This won't work because `alias this` is not inheritance ini the
- Danilo (9/13) Jan 18 Thanks for all the replies!
- Jonathan M Davis (20/25) Jan 18 The purpose of alias this is to add an implicit conversion to the target...
The following code does not work, and I think it may be a bug or could need an enhancement: ```d module app; import std; void main() { auto x = new Derived(10, 20); } struct Base { int a; } struct Derived { Base base; int b; alias this = base; disable this(); // `a` is not available for use with constructor parameters. // this( typeof(a) _a, typeof(b) _b ) { // // inside the body of the constructor, `a` is available! // a = _a; b = _b; writeln( a, ", ", b ); } } ``` The use of `typeof(a)` as a constructor parameter gives: Error: undefined identifier `a` Instead I have to explicitely use: ```d this( typeof(this.a) _a, typeof(b) _b ) // or this( typeof(base.a) _a, typeof(b) _b ) ``` I think this may be a bug, because `base` was imported into the scope using `alias this = base` and should therefore be available as plain `a`. With class inheritance everything works as expected: ```d module app; import std; class A { int x; } class B : A { int y; } class C : B { int z; this( typeof(x) _x, typeof(y) _y, typeof(z) _z) { writeln( _x, ", ", _y, ", ", _z ); } } void main() { new C(10, 20, 30); } ``` Could this please get improved a little bit, so "inherited" structure members using `alias this` are already available for constructor paramaters? Thanks!
Jan 17
On Thursday, 18 January 2024 at 07:10:49 UTC, Danilo wrote:Could this please get improved a little bit, so "inherited" structure members using `alias this` are already available for constructor paramaters? Thanks!Why can't struct be inherited ?C++ has good `struct inheritance`, and it's there. The disadvantage of `C++ inheritance` is that every `subclass` with a template now needs to add its `own name` and ugly `::`, which is becoming increasingly unsightly! This is `very foolish`,
Jan 17
On Thursday, 18 January 2024 at 07:28:22 UTC, zjh wrote:Why can't struct be inherited ?C++ has good `struct inheritance`, and it's there. The disadvantage of `C++ inheritance` is that every `subclass` with a template now needs to add its `own name` and ugly `::`, which is becoming increasingly unsightly! This is `very foolish`,I look forward to `someone` writing a `compiler plugin` that can compensate for `these shortcomings`. If the compiler allows `various plugins`, it would be very good. Plugins are completely selectable by users, which is equivalent to placing all the `switches` of `'dmd'` in a separate `plugins directory` .
Jan 17
On Thursday, 18 January 2024 at 07:32:56 UTC, zjh wrote:Plugins are completely selectable by users, which is equivalent to placing all the `switches` of `'dmd'` in a separate `plugins directory` .Then if you compile someone else's code, of course you need a plugin that someone else uses. However, there should be a `compilation command` that can control the `switch` of the plugin. Moreover, `each library` comes with its own `'compile command'` when released.
Jan 17
On Thursday, 18 January 2024 at 07:37:10 UTC, zjh wrote:Then if you compile someone else's code, of course you need a plugin that someone else uses. However, there should be a `compilation command` that can control the `switch` of the plugin. Moreover, `each library` comes with its own `'compile command'` when released.Can you please start your own thread? Your messages have absolutely nothing to do with my issue/request!
Jan 17
On Thursday, 18 January 2024 at 07:10:49 UTC, Danilo wrote:The following code does not work, and I think it may be a bug or could need an enhancement: ```d module app; import std; void main() { auto x = new Derived(10, 20); } struct Base { int a; } struct Derived { Base base; int b; alias this = base; disable this(); // `a` is not available for use with constructor parameters. // this( typeof(a) _a, typeof(b) _b ) { // // inside the body of the constructor, `a` is available! // a = _a; b = _b; writeln( a, ", ", b ); } } ``` The use of `typeof(a)` as a constructor parameter gives: Error: undefined identifier `a` Instead I have to explicitely use: ```d this( typeof(this.a) _a, typeof(b) _b ) // or this( typeof(base.a) _a, typeof(b) _b ) ```Just FYI, it's kind of a special case that `typeof(this)` works in this context -- there is no "this" at declaration level, it only exists as a parameter to a function. D allows using typeof(this) to mean "the type of an instance" during declarations because it would be awful otherwise. So I think you are playing around the edge of this "special case" and that's why it's not working. I'm actually surprised `typeof(this.a)` works. -Steve
Jan 18
On Thursday, 18 January 2024 at 07:10:49 UTC, Danilo wrote:The following code does not work, and I think it may be a bug or could need an enhancement: ```d module app; import std; void main() { auto x = new Derived(10, 20); } struct Base { int a; } struct Derived { Base base; int b; alias this = base; disable this(); // `a` is not available for use with constructor parameters. // this( typeof(a) _a, typeof(b) _b ) { // // inside the body of the constructor, `a` is available! // a = _a; b = _b; writeln( a, ", ", b ); } } ``` The use of `typeof(a)` as a constructor parameter gives: Error: undefined identifier `a` Instead I have to explicitely use: ```d this( typeof(this.a) _a, typeof(b) _b ) // or this( typeof(base.a) _a, typeof(b) _b ) ``` I think this may be a bug, because `base` was imported into the scope using `alias this = base` and should therefore be available as plain `a`. With class inheritance everything works as expected: ```d module app; import std; class A { int x; } class B : A { int y; } class C : B { int z; this( typeof(x) _x, typeof(y) _y, typeof(z) _z) { writeln( _x, ", ", _y, ", ", _z ); } } void main() { new C(10, 20, 30); } ``` Could this please get improved a little bit, so "inherited" structure members using `alias this` are already available for constructor paramaters? Thanks!This won't work because `alias this` is not inheritance ini the object oriented, class-based sense. All it does is when you try to access a symbol through a Derived struct (e.g. `Derived d; writeln(d.a);`) that the compiler sees does not exist in Derived, it will rewrite that to `Derived d; writeln(d.base.a);` (and also when you pass a Derived to a method taking a Base, it will automatically be rewritten to pass the Derived struct's Base member to the method instead). You really cannot think of `alias this` as inheritance, because it is not at all the same as the object-oriented concept of inheritance. You'll only run into problems thinking of it that way.
Jan 18
Thanks for all the replies! Of course the part "struct inheritance" was nonsense. The problem has nothing to do with, it's just about `alias this = xyz` inside classes and structs. On Thursday, 18 January 2024 at 20:43:30 UTC, Meta wrote:All it does is when you try to access a symbol through a Derived struct (e.g. `Derived d; writeln(d.a);`) that the compiler sees does not exist in Derived, it will rewrite that to `Derived d; writeln(d.base.a);`Perfect! Only thing is missing, that this works everywhere inside classes and structs - including method/constructor parameters. If `a` isn't found, replace it with `base.a`.
Jan 18
On Thursday, January 18, 2024 12:10:49 AM MST Danilo via Digitalmars-d wrote:The following code does not work, and I think it may be a bug or could need an enhancement:...Could this please get improved a little bit, so "inherited" structure members using `alias this` are already available for constructor paramaters?The purpose of alias this is to add an implicit conversion to the target. Inside of a struct, it does do some extra work when a symbol isn't recognized and then implicitly converts the this parameter using the alias this to see if that allows the symbol to work, but at its core, alias this really has nothing to do with inheritance. It's just an implicit conversion (and if anything, personally, I think that doing the implicit conversion on the this reference when it's not even explicitly used is just begging for trouble, and I wish that that had not been implemented). As for typeof, having it do implicit conversions seems like it would just be an avenue for bugs. And the situation with classes is completely different, because the members of a base class are actually members of the derived class, not simply brought in via implicit conversion. In general, alias this is a giant footgun - especially in the face of any kind of type introspection - and IMHO, you really should reconsider what you're doing any time that you use it. Unfortunately, it can be necessary for certain classes of things, but extending it to do more is probably the exact opposite of what we should be doing with it if we change it. - Jonathan M Davis
Jan 18
On Thursday, 18 January 2024 at 21:06:22 UTC, Jonathan M Davis wrote:As for typeof, having it do implicit conversions seems like it would just be an avenue for bugs.It's not typeof() that does it, it's the compiler that does it in the same way it usually does it. See answer to Meta, above. `alias this = xyz` inside classes and structs: 1. It's useful. And it's allowed to use it like in my first example, for "importing a struct into the main scope". I discovered the small issue when writing a constructor generator, and with this struct it didn't work. 2. It's also about consistency: In my opinion the (virtual) alias created by `alias this = xyz` inside struct/class needs to work everywhere inside the same class/struct. That's why asked if it may be a bug. It's at least an issue if it works only partly. Seen from a programming language design viewpoint, I think it should get enhanced a tiny bit to be more consistent.
Jan 18
Created an issue, so this can be checked: - https://issues.dlang.org/show_bug.cgi?id=24345
Jan 18