www.digitalmars.com         C & C++   DMDScript  

digitalmars.dip.ideas - Struct inheritance

reply Richard (Rikki) Andrew Cattermole <richard cattermole.co.nz> writes:
As an idea this has come up in Razvan's DConf 2024 talk.

1. Support inheritance on struct, for other structs.

```d
struct Parent {
     ...
}

struct Child : Parent {
     ...
}
```

2. ``opDispatch`` function, may work in place of ``alias this`` 
when no parent exists.

```d
struct Parent {
     T thing;
     ref T opDispatch(string:"")() {
         return this.thing;
     }
}

struct Child : Parent {
}

Child child;
T got = child;
```
Sep 19
next sibling parent reply Nick Treleaven <nick geany.org> writes:
On Thursday, 19 September 2024 at 15:56:06 UTC, Richard (Rikki) 
Andrew Cattermole wrote:
 As an idea this has come up in Razvan's DConf 2024 talk.

 1. Support inheritance on struct, for other structs.

 ```d
 struct Parent {
     ...
 }

 struct Child : Parent {
     ...
 }
 ```
In the talk, Walter mentioned doing that instead of having `alias this`. That would be much less powerful. `alias this` allows hooking conversion to the target type. With `alias this = func; T func();`, you can create the T instance at runtime. It doesn't even have to be the same instance each time. Also T doesn't have to be a struct.
 2. ``opDispatch`` function, may work in place of ``alias this`` 
 when no parent exists.

 ```d
 struct Parent {
     T thing;
     ref T opDispatch(string:"")() {
         return this.thing;
     }
 }

 struct Child : Parent {
 }

 Child child;
 T got = child;
 ```
This seems like `alias this` in disguise.
Sep 19
parent reply "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
On 20/09/2024 6:57 AM, Nick Treleaven wrote:
 This seems like |alias this| in disguise.
The problem with alias this, is it is not defined as the fallback when nothing else in the hierarchy matches. Here it is better defined, opDispatch should only be chosen after exhausting the hierarchy, both in classes and structs. Eliminating the issues with alias this from the design. We can further restrict it, to only support the parent most type in the hierarchy or only one in the hierarchy. In effect it allows adding a new parent to the top of the hierarchy.
Sep 19
next sibling parent "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
On 20/09/2024 7:04 AM, Richard (Rikki) Andrew Cattermole wrote:
 On 20/09/2024 6:57 AM, Nick Treleaven wrote:
 This seems like |alias this| in disguise.
The problem with alias this, is it is not defined as the fallback when nothing else in the hierarchy matches. Here it is better defined, opDispatch should only be chosen after exhausting the hierarchy, both in classes and structs. Eliminating the issues with alias this from the design. We can further restrict it, to only support the parent most type in the hierarchy or only one in the hierarchy. In effect it allows adding a new parent to the top of the hierarchy.
I should mention that this aspect of the proposal while it add new semantics, doesn't have anything special related to the rules of acceptability of opDispatch itself. We'll need to define how opDispatch works in the hierarchy. Otherwise we'll have come right back to the same set of issues as alias this has.
Sep 19
prev sibling parent reply Nick Treleaven <nick geany.org> writes:
On Thursday, 19 September 2024 at 19:04:40 UTC, Richard (Rikki) 
Andrew Cattermole wrote:
 On 20/09/2024 6:57 AM, Nick Treleaven wrote:
 This seems like |alias this| in disguise.
The problem with alias this, is it is not defined as the fallback when nothing else in the hierarchy matches. Here it is better defined, opDispatch should only be chosen after exhausting the hierarchy, both in classes and structs.
I don't see why you want to overload opDispatch to do subtyping. It doesn't seem related to existing opDispatch.
 Eliminating the issues with alias this from the design.

 We can further restrict it, to only support the parent most 
 type in the hierarchy or only one in the hierarchy. In effect 
 it allows adding a new parent to the top of the hierarchy.
I don't think we need to restrict its capabilities, we just need another syntax for it so we can fix the semantics. If anything I'd like to increase its capabilities. It could be defined as a template method and instantiated with the type of the expected result, and the constraint determines whether the conversion is enabled for that type. In effect, allowing multiple `alias this` with the semantics defined by the aggregate author.
Sep 20
next sibling parent "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
On 21/09/2024 3:23 AM, Nick Treleaven wrote:
     Eliminating the issues with alias this from the design.
 
     We can further restrict it, to only support the parent most type in
     the hierarchy or only one in the hierarchy. In effect it allows
     adding a new parent to the top of the hierarchy.
 
 I don't think we need to restrict its capabilities, we just need another 
 syntax for it so we can fix the semantics. If anything I'd like to 
 increase its capabilities. It could be defined as a template method and 
 instantiated with the type of the expected result, and the constraint 
 determines whether the conversion is enabled for that type. In effect, 
 allowing multiple |alias this| with the semantics defined by the 
 aggregate author.
Ok so basically implicit conversions with optional target type. As long as it is defined as being last resort after looking up through the hierarchy, then that aspect I'm ok with. Child most definition only. You'll need to convince Walter wrt. argument to parameter matching, and he has some strong feelings on this. But as far as the syntax changes are concerned for no target type, I'm ok with that being swapped to, it'll give it somewhere to expand to in the future.
Sep 20
prev sibling parent user1234 <user1234 12.de> writes:
On Friday, 20 September 2024 at 15:23:25 UTC, Nick Treleaven 
wrote:
 On Thursday, 19 September 2024 at 19:04:40 UTC, Richard (Rikki) 
 Andrew Cattermole wrote:
 On 20/09/2024 6:57 AM, Nick Treleaven wrote:
 This seems like |alias this| in disguise.
The problem with alias this, is it is not defined as the fallback when nothing else in the hierarchy matches. Here it is better defined, opDispatch should only be chosen after exhausting the hierarchy, both in classes and structs.
I don't see why you want to overload opDispatch to do subtyping. It doesn't seem related to existing opDispatch.
 Eliminating the issues with alias this from the design.

 We can further restrict it, to only support the parent most 
 type in the hierarchy or only one in the hierarchy. In effect 
 it allows adding a new parent to the top of the hierarchy.
I don't think we need to restrict its capabilities, we just need another syntax for it so we can fix the semantics. If anything I'd like to increase its capabilities. It could be defined as a template method and instantiated with the type of the expected result, and the constraint determines whether the conversion is enabled for that type. [...]
It's basically the same as `opCast` but called without `cast`. A long time ago this was discussed, (we called that opImpcConvRight). That thing would work but to fix `alias this` problems then the users need to overload much more operators, and that becomes unatural to use, i.e vs `alias this` which works more naturally. Fact is there are plenty of situation where implicit convs are not tried but you want that new op to be tried. Basically that's the exact same situations where currently the compiler has to try if `alias this` is possible.
Sep 20
prev sibling next sibling parent Paul Backus <snarwin gmail.com> writes:
On Thursday, 19 September 2024 at 15:56:06 UTC, Richard (Rikki) 
Andrew Cattermole wrote:
 As an idea this has come up in Razvan's DConf 2024 talk.
Last time this came up on the forums, I did a quick search through Phobos to see how many uses of `alias this` forwarded to a member variable (and could be replaced by struct inheritance) and how many forwarded to a function. My hypothesis before actually checking was that `alias this` to a member variable would be significantly more common than `alias this` to a function. But in reality, they turned out to be equally common. Original post: https://forum.dlang.org/post/nbysytbybvqwgxvdexym forum.dlang.org
Sep 19
prev sibling next sibling parent reply IchorDev <zxinsworld gmail.com> writes:
On Thursday, 19 September 2024 at 15:56:06 UTC, Richard (Rikki) 
Andrew Cattermole wrote:
 As an idea this has come up in Razvan's DConf 2024 talk.

 1. Support inheritance on struct, for other structs.
 2. ``opDispatch`` function, may work in place of ``alias this`` 
 when no parent exists.
What about interfaces?
Sep 20
parent "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
On 20/09/2024 10:14 PM, IchorDev wrote:
 On Thursday, 19 September 2024 at 15:56:06 UTC, Richard (Rikki) Andrew 
 Cattermole wrote:
 As an idea this has come up in Razvan's DConf 2024 talk.

 1. Support inheritance on struct, for other structs.
 2. ``opDispatch`` function, may work in place of ``alias this`` when 
 no parent exists.
What about interfaces?
While I do want signatures which would fill this void, the purpose of this is to get rid of alias this which has some problematic behaviors in symbol lookup.
Sep 20
prev sibling parent reply Ogion <ogion.art gmail.com> writes:
On Thursday, 19 September 2024 at 15:56:06 UTC, Richard (Rikki) 
Andrew Cattermole wrote:
Would be nice to have proper struct inheritance but there are a lot of things we have to consider. What about slicing? ```D struct A { int x; } struct B : A { int y; this(int x, int y) { super(x); this.y = y; } } void main() { B b1 = B(1, 2), b2 = B(3, 4); A* p = &b2; *p = b1; writeln(b2); // B(1, 4) } ``` If we want something better than `alias this`, we have to prohibit implicit partial assignment via pointer/reference. When it’s necessary, it would still be possible with `*p = cast(A)b1;`.
Sep 23
next sibling parent "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
On 24/09/2024 2:52 AM, Ogion wrote:
 On Thursday, 19 September 2024 at 15:56:06 UTC, Richard (Rikki) Andrew 
 Cattermole wrote:
Would be nice to have proper struct inheritance but there are a lot of things we have to consider. What about slicing? ```D struct A {     int x; } struct B : A {     int y;     this(int x, int y) {         super(x);         this.y = y;     } } void main() {     B b1 = B(1, 2), b2 = B(3, 4);     A* p = &b2;     *p = b1;     writeln(b2); // B(1, 4) } ``` If we want something better than `alias this`, we have to prohibit implicit partial assignment via pointer/reference. When it’s necessary, it would still be possible with `*p = cast(A)b1;`.
It is probably better to completely disable casting up the hierarchy in `` safe`` code. If you need that, use ``opCast``. It is not like with classes, where its guaranteed to have an allocation containing the entire thing, with a vtable. Only concern is when you've got a pointer to a struct, and you cast up. ``opCast!(A*)`` support is likely what we want I think. I'm not sure how we'd do that one. Maybe an attribute?
Sep 23
prev sibling parent Brad Roberts <braddr puremagic.com> writes:
On 9/23/2024 7:52 AM, Ogion via dip.ideas wrote:
 On Thursday, 19 September 2024 at 15:56:06 UTC, Richard (Rikki) Andrew 
 Cattermole wrote:
Would be nice to have proper struct inheritance but there are a lot of things we have to consider.
Careful with the term 'proper'. It doesn't add clarity. It does implicitly divide everything else into some vague other category of improper, but without actually helping describe any actual particulars.
Sep 23