June 14, 2019
On Thursday, 13 June 2019 at 23:28:37 UTC, Manu wrote:
> On Thu, Jun 13, 2019 at 4:05 PM 12345swordy via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>>
>> On Thursday, 13 June 2019 at 22:12:37 UTC, Manu wrote:
>> > On Thu, Jun 13, 2019 at 7:55 AM 12345swordy via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>> >>
>> >> > [...] It's not better.
>> >>
>> >> Wouldn't it be better to allow structs to implement static only interfaces?
>> >
>> > I don't know what that means? Like D `interface`, which is a pure vtable with no data members? That's the opposite of what I want... what is a 'static' interface?
>>
>> Interface with only static functions and data members. No virtual function what so ever.
>
> Well... right. We're talking about struct's here. struct's don't have virtual functions.
I am saying that structs should be allow to inherent interfaces, provided that said interface only contains statics functions(with or without implementation) or data members.

What you want is the ability to define a contract for the structs to inherited without any virtual functions.

June 14, 2019
On Thursday, 13 June 2019 at 22:13:51 UTC, Manu wrote:

>
> So don't implicitly convert to the base type?
> B extends A, but I don't think it's a kind of A as for polymorphic classes.

So you want

class Foo : BaseClass {}

and

struct Bar : BaseStruct {}

to produce two different results?
June 13, 2019
On Thu, Jun 13, 2019 at 6:13 PM 12345swordy via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>
> On Thursday, 13 June 2019 at 23:28:37 UTC, Manu wrote:
> > On Thu, Jun 13, 2019 at 4:05 PM 12345swordy via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
> >>
> >> On Thursday, 13 June 2019 at 22:12:37 UTC, Manu wrote:
> >> > On Thu, Jun 13, 2019 at 7:55 AM 12345swordy via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
> >> >>
> >> >> > [...] It's not better.
> >> >>
> >> >> Wouldn't it be better to allow structs to implement static only interfaces?
> >> >
> >> > I don't know what that means? Like D `interface`, which is a pure vtable with no data members? That's the opposite of what I want... what is a 'static' interface?
> >>
> >> Interface with only static functions and data members. No virtual function what so ever.
> >
> > Well... right. We're talking about struct's here. struct's don't have virtual functions.
> I am saying that structs should be allow to inherent interfaces, provided that said interface only contains statics functions(with or without implementation) or data members.

I think that's much more weird than struct's inheriting a struct... an interface is everything other than a static non-virtual type... a struct is *exactly* that.

> What you want is the ability to define a contract for the structs to inherited without any virtual functions.

I would expect something different from a "contract"; that sounds like some expectations without some concrete details defined. And again, this is the opposite of that.
June 13, 2019
On Thu, Jun 13, 2019 at 9:20 PM Mike Parker via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>
> On Thursday, 13 June 2019 at 22:13:51 UTC, Manu wrote:
>
> >
> > So don't implicitly convert to the base type?
> > B extends A, but I don't think it's a kind of A as for
> > polymorphic classes.
>
> So you want
>
> class Foo : BaseClass {}
>
> and
>
> struct Bar : BaseStruct {}
>
> to produce two different results?

Well, one's a class and the other's a struct, and that means what it means.
June 14, 2019
On Friday, 14 June 2019 at 05:59:25 UTC, Manu wrote:

>> So you want
>>
>> class Foo : BaseClass {}
>>
>> and
>>
>> struct Bar : BaseStruct {}
>>
>> to produce two different results?
>
> Well, one's a class and the other's a struct, and that means what it means.

It means inconsistency, IMO, and a new violation of the principle of least astonishment. I have nothing against the behavior you want, but if it's going to behave differently from polymorphic inheritance, then it should look different.
June 14, 2019
On Thursday, 13 June 2019 at 22:13:51 UTC, Manu wrote:
>
> So don't implicitly convert to the base type?
> B extends A, but I don't think it's a kind of A as for polymorphic classes.

What is the benefit of

	struct A { void fun(); };
	struct B :A {};

	B b;
	b.fun;

compared to

	struct A {};
	struct B { A a; };

	B b;
	b.a.fun;

Less typing is good but stuff happening magically/unexpectedly for a neutral reader of the code (e.g. implicit casts) is not. And if on the other hand, !is(B:A), then what is the advantage, and the use case?

Your OP pattern may have good alternatives that don't repeat code either, but produce more explicitly readable code?
June 14, 2019
On Friday, 14 June 2019 at 14:47:15 UTC, XavierAP wrote:
> On Thursday, 13 June 2019 at 22:13:51 UTC, Manu wrote:
>>
>> So don't implicitly convert to the base type?
>> B extends A, but I don't think it's a kind of A as for polymorphic classes.
>
> Less typing is good but stuff happening magically/unexpectedly for a neutral reader of the code (e.g. implicit casts) is not. And if on the other hand, !is(B:A), then what is the advantage, and the use case?

Moreover, even if your inheritance did not produce (static) polymorphism in the hard sense i.e. !is(B:A), it would in the duck-typed sense, in templates! So inheritance without polymorphism is inconsistent.

	struct A { void fun(); };
	struct B :A {};
	
	void gun(A x)    { x.fun; }
	void hun(T)(T x) { x.fun; }
	
	B b;
	b.gun; // error?
	b.hun; // ok
June 14, 2019
On Thursday, 13 June 2019 at 22:12:37 UTC, Manu wrote:
> what is a 'static' interface?

I would define it as something like this:

static interface Processor
{
  // Required methods for a struct
  void prepare(Options opts);
  void process(ubyte[] data);
  bool isReady();
  Result get();

  int integer; // No size, just a requirement
}

struct IncorrectProcessor : Processor
{
  void prepare(Options opts) { ... }
  void doSomething() { ... }
}

// Implements all that's in the 'static interface' even the (public) data.
struct CorrectProcessor : Processor
{
  void prepare(Options opts) { ... }
  void process(ubyte[] data) { ... }
  bool isReady() { ... }
  Result get() { ... }

  int integer;

  void doSomething2() { ... }
  void doSomething3() { ... }
}

void myProcessorUseCase(Processor p)
{
  p.prepare(opts);
  p.process(data);
  while(!p.isReady()) { ... }
  return p.get();
}

// You can now call myProcessorUseCase with different types of processors with in different parts of code. No runtime type switching, no virtuals.

myProcessorUseCase( incorrectProcessor ); // Error: 'incorrectProcessor' doesn't implement static interface 'Processor' correctly

myProcessorUseCase( correctProcessor ); // OK

-----
Basically, a static compile-time check that struct is of specific form. Kind of like compiling a different .c file for a shared/interface .h file for different builds, except not restricted to files and builds.
No virtuals or anything. Compiling doesn't produce any artifacts just does the check.

I've often wished for a feature like this. I suppose you can do template constraints, static ifs and meta, but honestly I find the result cumbersome and not very readable/debuggable.

June 15, 2019
On Thursday, 13 June 2019 at 12:20:14 UTC, Patrick Schluter wrote:
>> If you try to malloc some number of zero-sized types naively, you'll pass an allocation size of 0 to the allocator, which is implementation-defined at best. Also you want to avoid allocating these things anyway!
>>
> Especially if you use C allocation realloc() as calling it with size 0 is synonymous to free(). Ouch!

When would that be a problem? Any pointer is a valid pointer for a zero-sized object, as it can never be meaningfully "dereferenced" (never minding only pretending to do that for purposes of metaprogramming and such).

June 15, 2019
On Saturday, 15 June 2019 at 10:19:25 UTC, Vladimir Panteleev wrote:
> On Thursday, 13 June 2019 at 12:20:14 UTC, Patrick Schluter wrote:
>> Especially if you use C allocation realloc() as calling it with size 0 is synonymous to free(). Ouch!
>
> When would that be a problem? Any pointer is a valid pointer for a zero-sized object, as it can never be meaningfully "dereferenced" (never minding only pretending to do that for purposes of metaprogramming and such).

Oh, I guess it would be an issue if you tried to grow it back to non-zero size.