Re: How to do "inheritance" in D structs

2016-10-12 Thread cym13 via Digitalmars-d-learn

On Wednesday, 12 October 2016 at 02:33:20 UTC, lobo wrote:
On Wednesday, 12 October 2016 at 02:18:47 UTC, TheFlyingFiddle 
wrote:

On Wednesday, 12 October 2016 at 01:22:04 UTC, lobo wrote:

Hi,

I'm coming from C++ and wondered if the pattern below has an 
equivalent in D using structs. I could just use classes and 
leave it up to the caller to use scoped! as well but I'm not 
sure how that will play out when others start using my lib.


Thanks,
lobo


module A;

class Base1 {
int ival = 42;
}
class Base2 {
int ival = 84;
}

module B;

class S(ABase) : ABase {
string sval = "hello";
}

module C;

import A;
import B;

void main() {
auto s= scoped!(S!Base1); // scoped!(S!Base2)
}


You could use "alias this" to simulate that type of 
inheritence.


module A;
struct Base1
{
int ival = 42;
}

module B;

struct Base2
{
int ival = 84;
}

module C;
import A, B;

struct S(Base) if(is(Base == struct))
{
Base base;
alias base this;
string sval = "Hello ";
}

void foo(ref ABase base)
{
base.ival = 32;
}

void main()
{
S!Base1 a;
S!Base2 b;
writeln(a.sval, a.ival);
writeln(b.sval, b.ival);
foo(a);
writeln(a.sval, a.ival);
}


This approach works nicely although it feels clumsy but that's 
probably just because I'm so used to C++. It also handles 
private members as I'd expect, i.e. they're not accessible 
outside module scope through the alias struct instance, but 
there is no protected. Protected appears to behave the same way 
as private.


I think I can live with that because I usually try to avoid 
protected anyway.


Thanks,
lobo


Note that alias this is not inheritance, it's subtyping. What 
happens when doing:


struct P { int val = 42; }
struct S { P p; alias p this; }
assert(S().val == 42);

is that S tries to find “ this.val ”. First it looks in its scope 
without success. Then it uses the alias to transform “ this.val ” 
into “ p.val ”, but the type S isn't linked to the type P. When 
using attributes of p you are really dealing with a real object 
of type P. It also means that implicit conversion of S in P will 
just copy the p member:


struct P {
int val = 42;
}

struct S {
P p;
alias p this;
int val = 1234;
}

void main(string[] args) {
P p = S();
assert(p.val == 42);
}

Assert this is a great feature but it has to be well understood.


Re: How to do "inheritance" in D structs

2016-10-11 Thread Jacob Carlborg via Digitalmars-d-learn

On 2016-10-12 03:22, lobo wrote:

Hi,

I'm coming from C++ and wondered if the pattern below has an equivalent
in D using structs. I could just use classes and leave it up to the
caller to use scoped! as well but I'm not sure how that will play out
when others start using my lib.

Thanks,
lobo


module A;

class Base1 {
int ival = 42;
}
class Base2 {
int ival = 84;
}

module B;

class S(ABase) : ABase {
string sval = "hello";
}

module C;

import A;
import B;

void main() {
auto s= scoped!(S!Base1); // scoped!(S!Base2)
}


Depending on what you need, any alternative to structs and "alias this" 
would be to use structs with template mixins [1]:


mixin template Base1()
{
int ival = 42;
}

struct S(ABase)
{
mixin ABase;
}

What's in the struct will take precedence of what's in the template 
mixin. It's also possible to mix in several templates.


[1] http://dlang.org/spec/template-mixin.html

--
/Jacob Carlborg


Re: How to do "inheritance" in D structs

2016-10-11 Thread Jacob Carlborg via Digitalmars-d-learn

On 2016-10-12 04:33, lobo wrote:


This approach works nicely although it feels clumsy but that's probably
just because I'm so used to C++. It also handles private members as I'd
expect, i.e. they're not accessible outside module scope through the
alias struct instance, but there is no protected. Protected appears to
behave the same way as private.

I think I can live with that because I usually try to avoid protected
anyway.


I only expect "protected" to work with real inheritance, i.e. classes. 
Note that there's "package" protection attribute as well.


--
/Jacob Carlborg


Re: How to do "inheritance" in D structs

2016-10-11 Thread lobo via Digitalmars-d-learn
On Wednesday, 12 October 2016 at 02:18:47 UTC, TheFlyingFiddle 
wrote:

On Wednesday, 12 October 2016 at 01:22:04 UTC, lobo wrote:

Hi,

I'm coming from C++ and wondered if the pattern below has an 
equivalent in D using structs. I could just use classes and 
leave it up to the caller to use scoped! as well but I'm not 
sure how that will play out when others start using my lib.


Thanks,
lobo


module A;

class Base1 {
int ival = 42;
}
class Base2 {
int ival = 84;
}

module B;

class S(ABase) : ABase {
string sval = "hello";
}

module C;

import A;
import B;

void main() {
auto s= scoped!(S!Base1); // scoped!(S!Base2)
}


You could use "alias this" to simulate that type of inheritence.

module A;
struct Base1
{
int ival = 42;
}

module B;

struct Base2
{
int ival = 84;
}

module C;
import A, B;

struct S(Base) if(is(Base == struct))
{
Base base;
alias base this;
string sval = "Hello ";
}

void foo(ref ABase base)
{
base.ival = 32;
}

void main()
{
S!Base1 a;
S!Base2 b;
writeln(a.sval, a.ival);
writeln(b.sval, b.ival);
foo(a);
writeln(a.sval, a.ival);
}


This approach works nicely although it feels clumsy but that's 
probably just because I'm so used to C++. It also handles private 
members as I'd expect, i.e. they're not accessible outside module 
scope through the alias struct instance, but there is no 
protected. Protected appears to behave the same way as private.


I think I can live with that because I usually try to avoid 
protected anyway.


Thanks,
lobo



Re: How to do "inheritance" in D structs

2016-10-11 Thread TheFlyingFiddle via Digitalmars-d-learn
On Wednesday, 12 October 2016 at 02:18:47 UTC, TheFlyingFiddle 
wrote:

void foo(ref ABase base)
{
base.ival = 32;
}

This should be:
void foo(ref Base1 base)
{
base.ival = 32;
}



Re: How to do "inheritance" in D structs

2016-10-11 Thread TheFlyingFiddle via Digitalmars-d-learn

On Wednesday, 12 October 2016 at 01:22:04 UTC, lobo wrote:

Hi,

I'm coming from C++ and wondered if the pattern below has an 
equivalent in D using structs. I could just use classes and 
leave it up to the caller to use scoped! as well but I'm not 
sure how that will play out when others start using my lib.


Thanks,
lobo


module A;

class Base1 {
int ival = 42;
}
class Base2 {
int ival = 84;
}

module B;

class S(ABase) : ABase {
string sval = "hello";
}

module C;

import A;
import B;

void main() {
auto s= scoped!(S!Base1); // scoped!(S!Base2)
}


You could use "alias this" to simulate that type of inheritence.

module A;
struct Base1
{
int ival = 42;
}

module B;

struct Base2
{
int ival = 84;
}

module C;
import A, B;

struct S(Base) if(is(Base == struct))
{
Base base;
alias base this;
string sval = "Hello ";
}

void foo(ref ABase base)
{
base.ival = 32;
}

void main()
{
S!Base1 a;
S!Base2 b;
writeln(a.sval, a.ival);
writeln(b.sval, b.ival);
foo(a);
writeln(a.sval, a.ival);
}