Jump to page: 1 28  
Page
Thread overview
Why can't we derive struct's?
Dec 20, 2018
Manu
Dec 20, 2018
Basile B.
Dec 20, 2018
Manu
Dec 20, 2018
Rubn
Dec 20, 2018
Walter Bright
Dec 20, 2018
Manu
Dec 20, 2018
Manu
Dec 20, 2018
H. S. Teoh
Re: Why can't we derive struct's? (Hansel & Gretel)
Dec 21, 2018
Walter Bright
Dec 21, 2018
Manu
Dec 21, 2018
Walter Bright
Dec 27, 2018
Jonathan M Davis
Dec 28, 2018
luckoverthere
Dec 28, 2018
H. S. Teoh
Dec 28, 2018
luckoverthere
Dec 28, 2018
H. S. Teoh
Dec 21, 2018
12345swordy
Dec 21, 2018
Atila Neves
Dec 21, 2018
Walter Bright
Dec 21, 2018
Atila Neves
Dec 21, 2018
Walter Bright
Dec 21, 2018
Mike Franklin
Dec 21, 2018
H. S. Teoh
Dec 22, 2018
Atila Neves
Dec 26, 2018
Walter Bright
Dec 26, 2018
luckoverthere
Dec 21, 2018
Walter Bright
Dec 21, 2018
Walter Bright
Dec 21, 2018
H. S. Teoh
Dec 24, 2018
Walter Bright
Dec 24, 2018
12345swordy
Dec 24, 2018
H. S. Teoh
Dec 24, 2018
12345swordy
Dec 24, 2018
H. S. Teoh
Dec 24, 2018
12345swordy
Dec 24, 2018
Walter Bright
Dec 24, 2018
H. S. Teoh
Dec 24, 2018
Walter Bright
Dec 24, 2018
H. S. Teoh
Dec 24, 2018
Walter Bright
Dec 24, 2018
H. S. Teoh
Dec 26, 2018
bpr
Dec 24, 2018
12345swordy
Dec 24, 2018
Rubn
Dec 25, 2018
12345swordy
Dec 25, 2018
jmh530
Dec 26, 2018
12345swordy
Dec 24, 2018
12345swordy
Dec 25, 2018
Rubn
Dec 25, 2018
H. S. Teoh
Dec 25, 2018
Rubn
Dec 25, 2018
Walter Bright
Dec 25, 2018
Rubn
Dec 27, 2018
Walter Bright
Dec 27, 2018
Rubn
Dec 25, 2018
Neia Neutuladh
Dec 21, 2018
Walter Bright
Dec 21, 2018
Nicholas Wilson
Dec 21, 2018
Walter Bright
Dec 20, 2018
H. S. Teoh
Dec 20, 2018
12345swordy
Dec 20, 2018
H. S. Teoh
Dec 20, 2018
12345swordy
Dec 20, 2018
H. S. Teoh
Dec 20, 2018
12345swordy
Dec 20, 2018
H. S. Teoh
Dec 21, 2018
Timon Gehr
Dec 21, 2018
Walter Bright
Dec 21, 2018
rikki cattermole
Dec 21, 2018
Timon Gehr
Dec 21, 2018
Walter Bright
Dec 20, 2018
Manu
Dec 21, 2018
Guillaume Piolat
T.A. Cargill on Multiple Inheritance
Dec 21, 2018
Walter Bright
December 19, 2018
I've long since become bored of this design decision. Is there good
reason for it?
Why should it be impossible to derive a struct?

It can just be a sugar for an `alias this`, but for a case of simple
inheritance, `alias this` can be tedious to spot and understand when
reading the code.
There's also the special case of an empty base-struct. I
**constantly** have to do this:

struct Derived
{
  static if (Base.tupleof.length == 0)
    ref inout(Base) base() inout { return *cast(inout(Base)*)&this; }
  else
    Base base;
  alias base this;

  // the things...
}

If not that, then the derived class gets an aligned field of nothing populated by one byte of empty base struct.

It also wastes the single `alias this` slot that we get in a no-multiple-alias-this world.

As far as I can tell, the decision is arbitrary... can we move past this?
December 20, 2018
On Thursday, 20 December 2018 at 01:40:02 UTC, Manu wrote:
> I've long since become bored of this design decision. Is there good
> reason for it?
> Why should it be impossible to derive a struct?
>
> It can just be a sugar for an `alias this`,

Yes but another possible semantic for a struct inheritance list would be the structural conformance, i.e duck types, but this will never happen in D since we use constraints for that.

This could even be used as a primitive, simple and clean template system, although restricted to struct/union:

    @dummy struct Base { void required(); }
    struct Foo : Base { void required(){} }
    // we don't expect a Base as param, but something that's conform with Base,
    // i.e something that can be statically verified to have `void required();`
    void call(@dummy Base base){}

Which in D translates to much, really much verbose and complex code:

    struct Base { void required(); }
    struct Foo  { void required(){} }
    void call(B)(B base)
    if (__traits(hasMember, B, "required") &&
        isSomeFuncion(...) &&
        is(ReturnType!(...) == void))
    {}

let's say if you want to be 100% exact because nowadays I tend not to use template constraints anymore excepted when they are needed for the correct dispatching to an overload, they are a loss of time otherwise (i know some will hate this alternative point of view... )
December 19, 2018
On Wed, Dec 19, 2018 at 6:10 PM Basile B. via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>
> On Thursday, 20 December 2018 at 01:40:02 UTC, Manu wrote:
> > I've long since become bored of this design decision. Is there
> > good
> > reason for it?
> > Why should it be impossible to derive a struct?
> >
> > It can just be a sugar for an `alias this`,
>
> Yes but another possible semantic for a struct inheritance list would be the structural conformance, i.e duck types, but this will never happen in D since we use constraints for that.
>
> This could even be used as a primitive, simple and clean template system, although restricted to struct/union:
>
>      @dummy struct Base { void required(); }
>      struct Foo : Base { void required(){} }
>      // we don't expect a Base as param, but something that's
> conform with Base,
>      // i.e something that can be statically verified to have
> `void required();`
>      void call(@dummy Base base){}
>
> Which in D translates to much, really much verbose and complex code:
>
>      struct Base { void required(); }
>      struct Foo  { void required(){} }
>      void call(B)(B base)
>      if (__traits(hasMember, B, "required") &&
>          isSomeFuncion(...) &&
>          is(ReturnType!(...) == void))
>      {}
>
> let's say if you want to be 100% exact because nowadays I tend not to use template constraints anymore excepted when they are needed for the correct dispatching to an overload, they are a loss of time otherwise (i know some will hate this alternative point of view... )

I think strong traits are a different thing, otherwise you're
conflating syntax with class inheritance, and nobody will expect that.
I mean, I love strong traits, but make them a proper thing.
Your suggestion is just kinda weird and nobody would anticipate that.
I see no good reason to collide with normal class inheritance syntax
that way.

And that said, I don't think your answer is a comment on *why* it's
not possible today :)
I'd like to know the reason it doesn't just work already.
December 20, 2018
On Thursday, 20 December 2018 at 01:40:02 UTC, Manu wrote:
> I've long since become bored of this design decision. Is there good
> reason for it?
> Why should it be impossible to derive a struct?
>
> It can just be a sugar for an `alias this`, but for a case of simple
> inheritance, `alias this` can be tedious to spot and understand when
> reading the code.
> There's also the special case of an empty base-struct. I
> **constantly** have to do this:
>
> struct Derived
> {
>   static if (Base.tupleof.length == 0)
>     ref inout(Base) base() inout { return *cast(inout(Base)*)&this; }
>   else
>     Base base;
>   alias base this;
>
>   // the things...
> }
>
> If not that, then the derived class gets an aligned field of nothing populated by one byte of empty base struct.
>
> It also wastes the single `alias this` slot that we get in a no-multiple-alias-this world.
>
> As far as I can tell, the decision is arbitrary... can we move past this?

I imagine inheritance comes with things like being able to cast a Derived* to Base*. How do you delete a Base* without knowing it is derived from? Same goes for "virtual" (C++) functions. Virtual destructors and all that vtable stuff you'd normally get aren't used in struct. Instead you need to use the class type with the garbage collector or some hacky work around with scoped. But classes organize their data any way they want, so you need to use a struct as a shell. Not really a because it's not possible, but just like we don't a lot of other stuff, it's a design decision that was made. Gotta poke Walter and see if he's in the "feel's like he doesn't owe us or anyone an explanation" kind of mood or not.
December 19, 2018
On 12/19/2018 5:40 PM, Manu wrote:
> I've long since become bored of this design decision. Is there good
> reason for it?

`alias this` can alias to a function, that doesn't work very well with the base class syntax (you also use alias this to a function).

> Why should it be impossible to derive a struct?

Because polymorphism makes little sense for a value type.

> static if (Base.tupleof.length == 0)

static if (Base.sizeof == 0)

> then the derived class

class? struct? Dessert topping? Floor wax?

https://www.youtube.com/watch?v=wPO8PqHGWFU
(too bad youtube pulled the video part, it's just audio)
December 20, 2018
On Wed, Dec 19, 2018 at 7:45 PM Walter Bright via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>
> On 12/19/2018 5:40 PM, Manu wrote:
> > I've long since become bored of this design decision. Is there good reason for it?
>
> `alias this` can alias to a function, that doesn't work very well with the base class syntax (you also use alias this to a function).

Right, by necessity, because an empty struct member takes padded space
in the aggregate.
I think C++ gets the empty-base-class mechanic right; it doesn't take space.

I'm demonstrating crappy code that appears extremely frequently in lieu. Perhaps you have a better suggestion?

> > Why should it be impossible to derive a struct?
>
> Because polymorphism makes little sense for a value type.

It's not really polymorphism without a vtable, just simple extension. `alias this` produces the same result, it's just more wordy, kinda ugly, and boilerplate-ey. It also hogs the `alias this` slot.

>  > static if (Base.tupleof.length == 0)
>
> static if (Base.sizeof == 0)

Empty struct has sizeof == 1 no? It certainly takes that many bytes as a member, and that 1 byte is naturally padded out to the alignment of the following member.
December 20, 2018
On 12/20/18 3:15 AM, Manu wrote:
> On Wed, Dec 19, 2018 at 7:45 PM Walter Bright via Digitalmars-d
> <digitalmars-d@puremagic.com> wrote:
>>
>> On 12/19/2018 5:40 PM, Manu wrote:
>>   > static if (Base.tupleof.length == 0)
>>
>> static if (Base.sizeof == 0)
> 
> Empty struct has sizeof == 1 no? It certainly takes that many bytes as
> a member, and that 1 byte is naturally padded out to the alignment of
> the following member.

Yes, it does take 1 byte. I believe the reasoning was so it could have a unique address and be used in an array.

It's the same in C++ as well, according to the Internet (except for the base class optimization allowance). Note that C++ compilers aren't *required* to implement this.

The difference between inheritance and manual inheritance (i.e. alias this and a member), is that with true inheritance there is no member that has to have it's own distinct address, so it's allowed to take up 0 space

But I would expect your boilerplate could be handled via mixin template pretty easily, then it becomes:

struct Derived
{
   mixin DeriveFrom!Base;
}

That it takes up the one alias this slot is a bummer, but really we should implement multiple-alias-this and that problem would be solved.

-Steve
December 20, 2018
On Thu, Dec 20, 2018 at 12:15:53AM -0800, Manu via Digitalmars-d wrote:
> On Wed, Dec 19, 2018 at 7:45 PM Walter Bright via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
[...]
> > > Why should it be impossible to derive a struct?
> >
> > Because polymorphism makes little sense for a value type.
> 
> It's not really polymorphism without a vtable, just simple extension. `alias this` produces the same result, it's just more wordy, kinda ugly, and boilerplate-ey. It also hogs the `alias this` slot.
[...]

Sigh... when is multiple alias this ever going to happen??


T

-- 
Being forced to write comments actually improves code, because it is easier to fix a crock than to explain it. -- G. Steele
December 20, 2018
On Thursday, 20 December 2018 at 15:29:50 UTC, H. S. Teoh wrote:
> On Thu, Dec 20, 2018 at 12:15:53AM -0800, Manu via Digitalmars-d wrote:
>> On Wed, Dec 19, 2018 at 7:45 PM Walter Bright via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
> [...]
>> > > Why should it be impossible to derive a struct?
>> >
>> > Because polymorphism makes little sense for a value type.
>> 
>> It's not really polymorphism without a vtable, just simple extension. `alias this` produces the same result, it's just more wordy, kinda ugly, and boilerplate-ey. It also hogs the `alias this` slot.
> [...]
>
> Sigh... when is multiple alias this ever going to happen??
>
>
> T

When IgorStepanov quit disappearing on us.
https://github.com/dlang/dmd/pull/8378

Alex
December 20, 2018
On Thu, Dec 20, 2018 at 03:44:34PM +0000, 12345swordy via Digitalmars-d wrote:
> On Thursday, 20 December 2018 at 15:29:50 UTC, H. S. Teoh wrote:
> > On Thu, Dec 20, 2018 at 12:15:53AM -0800, Manu via Digitalmars-d wrote:
> > > On Wed, Dec 19, 2018 at 7:45 PM Walter Bright via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
> > [...]
> > > > > Why should it be impossible to derive a struct?
> > > >
> > > > Because polymorphism makes little sense for a value type.
> > > 
> > > It's not really polymorphism without a vtable, just simple extension. `alias this` produces the same result, it's just more wordy, kinda ugly, and boilerplate-ey. It also hogs the `alias this` slot.
> > [...]
> > 
> > Sigh... when is multiple alias this ever going to happen??
> > 
> > 
> > T
> 
> When IgorStepanov quit disappearing on us. https://github.com/dlang/dmd/pull/8378
[...]

IIRC, that PR was blocked because of disagreements over how ambiguous symbols over multiple alias this types would be resolved.  Somebody needs to come up with a DIP with well-defined semantics for all the details and corner cases before this can move forward.


T

-- 
"Maybe" is a strange word.  When mom or dad says it it means "yes", but when my big brothers say it it means "no"! -- PJ jr.
« First   ‹ Prev
1 2 3 4 5 6 7 8