Thread overview
Cascading, variable mixins
Oct 01, 2007
Slavisa Radic
Oct 01, 2007
Slavisa Radic
Oct 02, 2007
BCS
October 01, 2007
Hello Folks,

I would like to augment a mixin with another mixin, which gets augmented by another mixin...and so forth

The most important design goal is, how to pass a mixin as parameter and the class which gets augmented by the mixin does not has to import the mixin.

My overall-goal is to be able to extend functionality of a class from outside, without the need to touch the class itself (kind of inter-type-declaration).

I managed to pass a template as an alias parameter to the class which was going to be augmented. This class was able to mix it in.

Next i tried to do the same with the template which gets mixed in. I parameterized it with an alias-parameter, and used the parameter as mixin.

However, this doesn't work. In order to parameterize the template, I had to instantiate it. This instantiated template then could not get mixed in in the class, as it was no template-name any-more.

To illustrate this a little bit:
---------------------------
import std.stdio;

class A(alias T)
{
    mixin T;
}
-------------------------

module b;
import std.stdio;

template B(alias T)
{
    public void foo()
    {
        writefln("This is template-code from Template B");
    }

    mixin T;
}
-------------------------------------------------------------------

module b2;

template B2()
{
    public void bar()
    {

        writefln("And This is Code from a different Template, namely Template B2");
    }
}
--------------------------------
private import a;
private import b;
private import b2;

int main(char[][] args)
{
    A! ( B! (B2) ) a = new A! ( B! (B2) ) ();
    a.foo();
    a.bar();
    return 0;
}
--------------------------------------------

Compiling this will result in the following error:
a.d:5: mixin T is not a template

And it's true. It is really no template as it gets instantiated in the main-function. The problem is, how to parameterize B without instantiating it?

I would realy apreciate it If somebody would have a solution for this, as I need it for my Master-Thesis. So please do not post comments like "why should somebody do such stuff" - there are people - e.g. me ;-)


October 01, 2007
"Slavisa Radic" <konfusious@gmx.de> wrote in message news:fdqo5g$2prv$1@digitalmars.com...
>
> To illustrate this a little bit:
> ---------------------------
> import std.stdio;
>
> class A(alias T)
> {
>    mixin T;
> }
> -------------------------
>
> module b;
> import std.stdio;
>
> template B(alias T)
> {
>    public void foo()
>    {
>        writefln("This is template-code from Template B");
>    }
>
>    mixin T;
> }
> -------------------------------------------------------------------
>
> module b2;
>
> template B2()
> {
>    public void bar()
>    {
>
>        writefln("And This is Code from a different Template, namely
> Template B2");
>    }
> }
> --------------------------------
> private import a;
> private import b;
> private import b2;
>
> int main(char[][] args)
> {
>    A! ( B! (B2) ) a = new A! ( B! (B2) ) ();
>    a.foo();
>    a.bar();
>    return 0;
> }
> --------------------------------------------

Try something like..

class A(alias T, Args...)
{
    mixin T!(Args);
}

...

auto a = new A!(B, B2)();
a.foo();
a.bar();

WOrks for me :)


October 01, 2007
hmm, ok, now we managed to extend the class without touching it. But unfortunatly, I forgot to mention that the templates shouldn't be touched from outside either. So the goal is to build a set of refinements of classes, which then should be plugged together in the main-method, in order to produce desired classes.

Your proposal was to make the amount of template-parameters for the target-class variadic. That leads to the necessity of changing the templates (template b) parameter-list.

What i'm looking for, is a way to build chains of mixins with arbitrary depth. The proposed solution is just of depth 2.

Your Solution:

a mixes in b
b mixes in b2
b mixes in b3
b mixes in b4
and so forth...

But I'm looking for a way to do:

a mixes in b
b mixes in b2
b2 mixes in b3
b3 mixes in b4
and so forth

But thanks for your interesting suggestion.


October 02, 2007
Reply to Slavisa,

>> To illustrate this a little bit:
> ---------------------------
> import std.stdio;
> class A(alias T)
> {
> mixin T;
> }
> -------------------------
> 
> module b;
> import std.stdio;
> template B(alias T)
> {
> public void foo()
> {
> writefln("This is template-code from Template B");
> }
> mixin T;
> }
> -------------------------------------------------------------------
> module b2;
> 
> template B2()
> {
> public void bar()
> {
> writefln("And This is Code from a different Template, namely
> Template B2");
> }
> }
> --------------------------------
> private import a;
> private import b;
> private import b2;
> int main(char[][] args)
> {
> A! ( B! (B2) ) a = new A! ( B! (B2) ) ();
> a.foo();
> a.bar();
> return 0;
> }
> --------------------------------------------

I haven't tried it but this may work

template B(alias T)
{
template inner()
{
public void foo()
{
writefln("This is template-code from Template B");
}
mixin T;
}
}

class A(alias T)
{
mixin T.inner;
}

auto a = new A! ( B!(B2) ) ();