June 11, 2019
On 11/06/2019 10:02 PM, Vladimir Panteleev wrote:
> We actually take advantage of this by declaring hashsets as void[0][Key].

Oh that's a neat trick, I just use a bool!
June 11, 2019
On Sunday, 9 June 2019 at 08:05:34 UTC, Manu wrote:
> I am really really tired of this pattern:
>
> struct DerivedStruct
> {
>     static if (BaseStruct.tupleof.length > 0)
>         BaseStruct base;
>     else
>         ref inout(BaseStruct) base() inout { return
> *cast(inout(BaseStruct)*)&this; }
>     alias base this;
>
>     // derived members
>     //...
> }
>
> Imagine if we could just write:
>
> struct DerivedStruct : BaseStruct
> {
>     // derived members
>     //...
> }
>
> Just imagine!

I like the idea! I use the `alias this` idiom everywhere, and it is not too evident to new people coming from other languages, there is an overhead in explaining and understanding what that thing does, which is simple by itself.

However, I do see some issues with using the existing inheritance syntax, as it creates some confusions and maybe some false expectations.

I would like to have something like:

struct Derived mixin Base
{
}

which is more clear in the intent and reuses a well established concept in the language.
June 11, 2019
On Tue, Jun 11, 2019 at 1:00 AM Walter Bright via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>
> On 6/11/2019 12:06 AM, Manu wrote:
> > On Mon, Jun 10, 2019 at 11:30 PM Walter Bright via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
> >>
> >> On 6/9/2019 10:52 PM, Manu wrote:
> >>> That is indeed the feature that necessitates my 'solution',
> >>
> >> Is it specifically for C++ interop,
> >
> > It occurs frequently in C++ interop, but that's only because most of
> > my code exists in C++.
> > I do, and will continue to use base structs in C++ and in D for
> > exactly the same reasons.
> > Every codebase I have ever worked in uses base struct's to DRY
> > liberally, thousands of engineers think this is fine, and I've never
> > heard anyone think it's unusual, or weird/problematic.
> >
> >> or you just want the zero size?
> >
> > A zero size solution removes the static if hack, but it doesn't remove
> > the alias this hack. I want to remove both hacks.
> > I can't stress enough that struct inheritance exists, it's extremely
> > common, and we will continue to do it as a completely normal practice
> > with no apology.
> > Please don't make our code ugly and unnecessarily difficult to
> > understand for no reason.
> >
> > If you fear misunderstanding with polymorphism, fear not; this is not C++, struct is strictly a value type, there is no vtable, no virtual, no override, etc... there would be compile errors at every turn if anyone ever confused struct inheritance for polymorphism. We have a HUGE advantage here...
>
> Can I ask again, in a different way, why do you need the 0 size?

To handle base structs with no members.
June 11, 2019
On Tuesday, 11 June 2019 at 18:19:05 UTC, Manu wrote:
> On Tue, Jun 11, 2019 at 1:00 AM Walter Bright via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>>
>> On 6/11/2019 12:06 AM, Manu wrote:
>> > On Mon, Jun 10, 2019 at 11:30 PM Walter Bright via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>> >>
>> >> On 6/9/2019 10:52 PM, Manu wrote:
>> >>> That is indeed the feature that necessitates my 'solution',
>> >>
>> >> Is it specifically for C++ interop,
>> >
>> > It occurs frequently in C++ interop, but that's only because most of
>> > my code exists in C++.
>> > I do, and will continue to use base structs in C++ and in D for
>> > exactly the same reasons.
>> > Every codebase I have ever worked in uses base struct's to DRY
>> > liberally, thousands of engineers think this is fine, and I've never
>> > heard anyone think it's unusual, or weird/problematic.
>> >
>> >> or you just want the zero size?
>> >
>> > A zero size solution removes the static if hack, but it doesn't remove
>> > the alias this hack. I want to remove both hacks.
>> > I can't stress enough that struct inheritance exists, it's extremely
>> > common, and we will continue to do it as a completely normal practice
>> > with no apology.
>> > Please don't make our code ugly and unnecessarily difficult to
>> > understand for no reason.
>> >
>> > If you fear misunderstanding with polymorphism, fear not; this is not C++, struct is strictly a value type, there is no vtable, no virtual, no override, etc... there would be compile errors at every turn if anyone ever confused struct inheritance for polymorphism. We have a HUGE advantage here...
>>
>> Can I ask again, in a different way, why do you need the 0 size?
>
> To handle base structs with no members.

Kind of curious, what do you use a base class for that has no members, is a size of zero, and also has no vtable or virtual functions?
June 11, 2019
On Tue, Jun 11, 2019 at 12:35 PM Exil via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>
> On Tuesday, 11 June 2019 at 18:19:05 UTC, Manu wrote:
> > On Tue, Jun 11, 2019 at 1:00 AM Walter Bright via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
> >>
> >> On 6/11/2019 12:06 AM, Manu wrote:
> >> > On Mon, Jun 10, 2019 at 11:30 PM Walter Bright via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
> >> >>
> >> >> On 6/9/2019 10:52 PM, Manu wrote:
> >> >>> That is indeed the feature that necessitates my 'solution',
> >> >>
> >> >> Is it specifically for C++ interop,
> >> >
> >> > It occurs frequently in C++ interop, but that's only because
> >> > most of
> >> > my code exists in C++.
> >> > I do, and will continue to use base structs in C++ and in D
> >> > for
> >> > exactly the same reasons.
> >> > Every codebase I have ever worked in uses base struct's to
> >> > DRY
> >> > liberally, thousands of engineers think this is fine, and
> >> > I've never
> >> > heard anyone think it's unusual, or weird/problematic.
> >> >
> >> >> or you just want the zero size?
> >> >
> >> > A zero size solution removes the static if hack, but it
> >> > doesn't remove
> >> > the alias this hack. I want to remove both hacks.
> >> > I can't stress enough that struct inheritance exists, it's
> >> > extremely
> >> > common, and we will continue to do it as a completely normal
> >> > practice
> >> > with no apology.
> >> > Please don't make our code ugly and unnecessarily difficult
> >> > to
> >> > understand for no reason.
> >> >
> >> > If you fear misunderstanding with polymorphism, fear not; this is not C++, struct is strictly a value type, there is no vtable, no virtual, no override, etc... there would be compile errors at every turn if anyone ever confused struct inheritance for polymorphism. We have a HUGE advantage here...
> >>
> >> Can I ask again, in a different way, why do you need the 0 size?
> >
> > To handle base structs with no members.
>
> Kind of curious, what do you use a base class for that has no members, is a size of zero, and also has no vtable or virtual functions?

Metaprogramming; it's a template argument.
It might be the case that some method is expected to exist, but the
particular implementation may or may not require any data.

Virtuals are dead man, nobody uses OOP anymore. It's all about
contracts and things like that.
Base classes might be expected to have a method, and there may be a
static assert to prove that some API is satisfied, but the
implementation may want to have some additional state.
This pattern doesn't exclusively apply to inheritance, but that's the
case on trial.
June 12, 2019
On 6/10/19 7:00 PM, H. S. Teoh wrote:
> On Mon, Jun 10, 2019 at 06:35:16PM -0400, Nick Sabalausky (Abscissa) via Digitalmars-d wrote:
>>
>> Would it really be a problem for the addresses of zero-byte structs to
>> just simply be null?
> 
> Probably, if people expect:
> 
> 	struct S {}
> 	S s;
> 	assert(&s !is null);
> 
> to work.

Ehh, maybe, but since when does anyone ever check a D struct's address for being null?

Even if you DID have a struct who's address was null (due to being zero size), then unlike for classes, using the struct's methods or static members would still be no problem since it wouldn't involve dereferencing the null (Instead, for the static members it's irrelevent entirely, and for the rest: it would just simply pass null as the hidden argument to member functions which - outside of @system pointer manipulation - would still have no way to actually dereference the null, because there's no non-static data members to even refer to, let alone access.)

Or, heck, even just have it share an address with another data member. That or the null thing, I see no realistic problem either way. Or if you really want to be needlessly clumsy about it, have an attribute or pragma or something that says "If this field is a zero-byte struct, then for the love of god make it zero byte, I don't even care how you do it."

I really don't like the whole "ships have sailed" theme in D though. It just gives a straight up middle finger to "The Last Thing D Needs" and to the whole reason for D's creation in the first place - to fix stupid legacy mistakes.

And yea, sure, of course we have bigger fish to fry. But that should never be a reason to say "The mistake is realistically fixable, but NO, never gonna anyway!" instead of "Right, that was a mistake and it's fixable. We should fix it sooner or later BUT it's not a high priority right now."
June 12, 2019
On 6/11/19 2:29 AM, Walter Bright wrote:
> 
> 2. How would you determine the dimension of an array of 0 size elements?

By reading .length instead of performing an unnecessary division.
June 12, 2019
On 6/11/19 3:56 AM, Walter Bright wrote:
> 
> Can I ask again, in a different way, why do you need the 0 size?
> 

In games programming, you frequently have (at least) one of two things:

A. A limited-resource embedded system that you're wringing every last bit of memory and performance out of.

B. At least several tens of gigabytes worth of content.

Either way, this makes *ANY* wasted per-instance overhead unacceptable.
June 11, 2019
On Wed, Jun 12, 2019 at 12:44:08AM -0400, Nick Sabalausky (Abscissa) via Digitalmars-d wrote:
> On 6/11/19 2:29 AM, Walter Bright wrote:
> > 
> > 2. How would you determine the dimension of an array of 0 size elements?
> 
> By reading .length instead of performing an unnecessary division.

+1.  I never liked that nonsensical sizeof(array)/sizeof(array[0]) "trick" or idiom.  It was a hack around a deficient language way back when.  Today we have D, and D has .length. We should be using that instead.  Why are we still bending over backwards to support outdated hacks?


T

-- 
Freedom of speech: the whole world has no right *not* to hear my spouting off!
June 11, 2019
On Wed, Jun 12, 2019 at 12:31:24AM -0400, Nick Sabalausky (Abscissa) via Digitalmars-d wrote:
> On 6/10/19 7:00 PM, H. S. Teoh wrote:
> > On Mon, Jun 10, 2019 at 06:35:16PM -0400, Nick Sabalausky (Abscissa) via Digitalmars-d wrote:
> > > 
> > > Would it really be a problem for the addresses of zero-byte structs to just simply be null?
> > 
> > Probably, if people expect:
> > 
> > 	struct S {}
> > 	S s;
> > 	assert(&s !is null);
> > 
> > to work.
> 
> Ehh, maybe, but since when does anyone ever check a D struct's address for being null?

I wouldn't say it occurs to structs specifically, but in generic code, it's conceivable you'd want to receive pointers and check whether they're actually pointing to something or if there's no value (e.g., using null as a kind of absence-of-data indicator).  There might be unexpected interaction with code that uses null for indicating, e.g., whether a container slot exists, which becomes problematic if null is also the address of an instance of a 0-sized type (thereby conflating "non-existent slot" with "slot exists but data is 0 bytes).

This is kinda contrived, though, and honestly I would vote for not supporting this sort of usage.  But it's the kind of thing certain people might get up in arms about, if this behaviour were changed.


> Or, heck, even just have it share an address with another data member. That or the null thing, I see no realistic problem either way. Or if you really want to be needlessly clumsy about it, have an attribute or pragma or something that says "If this field is a zero-byte struct, then for the love of god make it zero byte, I don't even care how you do it."

Maybe just alias it to void[0], like somebody proposed?


> I really don't like the whole "ships have sailed" theme in D though. It just gives a straight up middle finger to "The Last Thing D Needs" and to the whole reason for D's creation in the first place - to fix stupid legacy mistakes.

Personally, I agree that we shouldn't shy away from breaking changes if it improves the language for the long term.  After all, that's what the deprecation process is for.  But I'm not holding my breath for D leadership to buy into this sort of breaking change.


> And yea, sure, of course we have bigger fish to fry. But that should never be a reason to say "The mistake is realistically fixable, but NO, never gonna anyway!" instead of "Right, that was a mistake and it's fixable. We should fix it sooner or later BUT it's not a high priority right now."

In fact, I agree.  But I'm also not holding my breath for D leadership to change this attitude anytime soon. Cf. the bool fiasco, the char -> int implicit conversion (C promotion rules) fiasco, autodecoding (which is by now universally acknowledged as a mistake, but nobody has yet dared to take the first step to actually kill it), etc..

At some point, I seriously want to entertain the idea of D3. It used to be immediately shot down as not being likely, but with Andrei's recent change of stance about std.v2, there's a faint glimmer of hope that perhaps one day D3 could become reality.


T

-- 
Gone Chopin. Bach in a minuet.