Re: How to group similar member functions from different classes?

2016-07-18 Thread Marc Schütz via Digitalmars-d-learn

On Friday, 15 July 2016 at 17:25:23 UTC, cy wrote:

On Monday, 20 June 2016 at 16:39:54 UTC, Marc Schütz wrote:

Untested:


Seems to only work if A and B are both defined in the same file 
as Foos (defeating the purpose). Putting A and B in a.d and b.d 
respectively gives me these errors:


a.d(2): Error: undefined identifier 'Foos'
a.d(2): Error: mixin a.A.Foos!() is not defined
b.d(2): Error: undefined identifier 'Foos'
b.d(2): Error: mixin b.B.Foos!() is not defined

I also tried switching it around, like
// b.d
import foos Foos;
class B {
  mixin Foos;
}

but that of course gives the error:
foos.d(4): Error: undefined identifier 'A'
b.d(3): Error: mixin b.B.Foos!() error instantiating

since you can't do a static if(typeof(this) == A) without 
importing A from a somehow. (you can do else static 
if(typeof(this) == B) without importing B though, since it does 
the branch for A first)


I think a mixin here is just required, because you can't use an 
identifier before it's defined, even at compile time. Honestly, 
I have yet to find a use for mixin templates.


It works if you add forward declarations for the classes:

import a, b;
class A;
class B;
mixin template Foos() {
static if(is(typeof(this) == A))
void foo() { /* implementation for A */ }
static if(is(typeof(this) == B))
void foo() { /* implementation for B */ }
}



Re: How to group similar member functions from different classes?

2016-07-15 Thread cy via Digitalmars-d-learn

On Monday, 20 June 2016 at 16:39:54 UTC, Marc Schütz wrote:

Untested:


Seems to only work if A and B are both defined in the same file 
as Foos (defeating the purpose). Putting A and B in a.d and b.d 
respectively gives me these errors:


a.d(2): Error: undefined identifier 'Foos'
a.d(2): Error: mixin a.A.Foos!() is not defined
b.d(2): Error: undefined identifier 'Foos'
b.d(2): Error: mixin b.B.Foos!() is not defined

I also tried switching it around, like
// b.d
import foos Foos;
class B {
  mixin Foos;
}

but that of course gives the error:
foos.d(4): Error: undefined identifier 'A'
b.d(3): Error: mixin b.B.Foos!() error instantiating

since you can't do a static if(typeof(this) == A) without 
importing A from a somehow. (you can do else static 
if(typeof(this) == B) without importing B though, since it does 
the branch for A first)


I think a mixin here is just required, because you can't use an 
identifier before it's defined, even at compile time. Honestly, I 
have yet to find a use for mixin templates.


Re: How to group similar member functions from different classes?

2016-06-20 Thread Marc Schütz via Digitalmars-d-learn

Untested:

// foo.d
import a, b;
mixin template Foos {
static if(is(typeof(this) == A))
void foo() { /* implementation for A */ }
static if(is(typeof(this) == B))
void foo() { /* implementation for B */ }
}

// a.d
import foo;
class A {
mixin Foos;
}

// b.d
import foo;
class B {
mixin Foos;
}

You must not have static constructors in any of these modules 
because you'd likely get problems with circular initialization.


Re: How to group similar member functions from different classes?

2016-06-18 Thread kinke via Digitalmars-d-learn

On Saturday, 18 June 2016 at 07:03:25 UTC, cy wrote:
So how would you do it? Defining A.foo, B.foo, etc in one 
place, and A.bar, B.bar, etc in another?


No such thing in D. But you can always be creative and use an 
overloaded helper function containing the actual implementation 
if you want to group the code by functionality and not by type:


class A { int foo() { return doFoo(this); }
class B : A { int foo() { return doFoo(this); }

...

void doFoo(A a) { ... }
void doFoo(B b) { ... }

If you need full access to the members, the helpers would need to 
be in the same module, otherwise you can put them into a separate 
helper.


Re: How to group similar member functions from different classes?

2016-06-18 Thread cy via Digitalmars-d-learn

On Saturday, 18 June 2016 at 07:03:25 UTC, cy wrote:
So how would you do it? Defining A.foo, B.foo, etc in one 
place, and A.bar, B.bar, etc in another?


The only thing I've been able to figure is a horrible hack, where 
your member functions are something like


// off in define_foos.d

template foo_for(T) {
  static if(is(T == A)) {
enum foo_for = q{
  int foo () {
return bar+42;
  }
};
  } else static if(is(T == B)) {
enum foo_for = q{
  int foo () {
return bar+23;
  }
   };
  }
}

// in classes.d

import define_foos: foo_for;

struct A {
int bar;
mixin(foo_for!A);
}

struct B {
int bar;
mixin(foo_for!B);
}

// etc

void main() {
import std.stdio;
A a = A(0);
B b = B(1);
writeln(b.foo());
writeln(a.foo());
}


How to group similar member functions from different classes?

2016-06-18 Thread cy via Digitalmars-d-learn

When I define functions like:

class A {
  abstract void format(...) {...}
}

class B : A {
  void format(...) {...}
}

class C : A {
  void format(...) {...}
}

and so on, often these different member functions all share a lot 
in common. Maybe they are the only ones that require formatting 
modules, that do I/O, that do string manipulation, that sort of 
thing.


But if I made a second function, say for instance clone() or 
replaceWithDucks(), it too might import a lot of modules, and 
perform a lot of logic. And there may be many, many different 
types of object here.


In C++ I could forward declare the member functions, then put all 
"::format(...)" member functions together in their own source 
file, making everything pretty neat and tidy. How do I do that in 
D? As near as I can tell, you can only define member functions 
inside the class definition itself, and you can't add to that 
definition piece-wise like


// file 1
class A ... {
  void format(...) { ... }
}
...

// file 2
class A ... {
 void doathing() { ... }
}
...

So how would you do it? Defining A.foo, B.foo, etc in one place, 
and A.bar, B.bar, etc in another?