Thread overview
Question about Mixin.
Jun 19, 2013
Agustin
Jun 19, 2013
Ali Çehreli
Jun 19, 2013
Jonathan M Davis
Jun 20, 2013
monarch_dodra
Jun 20, 2013
Agustin
Jun 20, 2013
Agustin
Jun 19, 2013
Jonathan M Davis
June 19, 2013
Hello guys, my question is, its possible to write a mixin in a class, then if that class is inherited, the mixin will be written again instead of written the mixin again in the class child, for example:

Class A(T)
{
 mixin(WriteFunctionFor!(A));
}

Class B : A(B)
{
  ... -> mixin is written for B without need to write ("mixin(Write...))")
}

Class C : A(C)
{
  ... -> mixin is written for C without need to write ("mixin(Write...))")
}
June 19, 2013
On 06/19/2013 04:29 PM, Agustin wrote:
> Hello guys, my question is, its possible to write a mixin in a class,
> then if that class is inherited, the mixin will be written again instead
> of written the mixin again in the class child, for example:
>
> Class A(T)
> {
>   mixin(WriteFunctionFor!(A));
> }
>
> Class B : A(B)
> {
>    ... -> mixin is written for B without need to write ("mixin(Write...))")
> }
>
> Class C : A(C)
> {
>    ... -> mixin is written for C without need to write ("mixin(Write...))")
> }

Yes:

import std.stdio;

template WriteFunctionFor(T)
{
    T data;

    void foo()
    {
        writefln("I am working with a %s.", T.stringof);
    }
}

class A(T)
{
    mixin WriteFunctionFor!T;
}

class B : A!B
{}

class C : A!C
{}

void main()
{
    auto b = new B();
    b.foo();

    auto c = new C();
    c.foo();
}

The output:

I am working with a B.
I am working with a C.

Ali

June 19, 2013
On Thursday, June 20, 2013 01:29:48 Agustin wrote:
> Hello guys, my question is, its possible to write a mixin in a class, then if that class is inherited, the mixin will be written again instead of written the mixin again in the class child

No. If you want to put the same mixin in each of the derived classes, you must do so manually (though any public or protected functions mixed into the base class will be callable by the derived classes without mixing anything into them - just the same as if those functions were written directly in the base class).

- Jonathan M Davis
June 19, 2013
On Wednesday, June 19, 2013 16:35:16 Ali Çehreli wrote:
> On 06/19/2013 04:29 PM, Agustin wrote:
> > Hello guys, my question is, its possible to write a mixin in a class, then if that class is inherited, the mixin will be written again instead of written the mixin again in the class child, for example:
> > 
> > Class A(T)
> > {
> > 
> > mixin(WriteFunctionFor!(A));
> > 
> > }
> > 
> > Class B : A(B)
> > {
> > 
> > ... -> mixin is written for B without need to write
> > ("mixin(Write...))")
> > 
> > }
> > 
> > Class C : A(C)
> > {
> > 
> > ... -> mixin is written for C without need to write
> > ("mixin(Write...))")
> > 
> > }
> 
> Yes:
> 
> import std.stdio;
> 
> template WriteFunctionFor(T)
> {
> T data;
> 
> void foo()
> {
> writefln("I am working with a %s.", T.stringof);
> }
> }
> 
> class A(T)
> {
> mixin WriteFunctionFor!T;
> }
> 
> class B : A!B
> {}
> 
> class C : A!C
> {}
> 
> void main()
> {
> auto b = new B();
> b.foo();
> 
> auto c = new C();
> c.foo();
> }
> 
> The output:
> 
> I am working with a B.
> I am working with a C.

Ah, you're right. That will work. I misread the question. I thought that he was asking whether mixins in the base class magically got mixed in again into the derived class, which they don't.

- Jonathan M Davis
June 20, 2013
On Wednesday, 19 June 2013 at 23:35:16 UTC, Ali Çehreli wrote:
> On 06/19/2013 04:29 PM, Agustin wrote:
>> Hello guys, my question is, its possible to write a mixin in a class,
>> then if that class is inherited, the mixin will be written again instead
>> of written the mixin again in the class child, for example:
>>
>> Class A(T)
>> {
>>  mixin(WriteFunctionFor!(A));
>> }
>>
>> Class B : A(B)
>> {
>>   ... -> mixin is written for B without need to write ("mixin(Write...))")
>> }
>>
>> Class C : A(C)
>> {
>>   ... -> mixin is written for C without need to write ("mixin(Write...))")
>> }
>
> Yes:
>
> import std.stdio;
>
> template WriteFunctionFor(T)
> {
>     T data;
>
>     void foo()
>     {
>         writefln("I am working with a %s.", T.stringof);
>     }
> }
>
> class A(T)
> {
>     mixin WriteFunctionFor!T;
> }
>
> class B : A!B
> {}
>
> class C : A!C
> {}
>
> void main()
> {
>     auto b = new B();
>     b.foo();
>
>     auto c = new C();
>     c.foo();
> }
>
> The output:
>
> I am working with a B.
> I am working with a C.
>
> Ali

Thanks!, now i'm trying to do that but its not working :(.

template Eventable(T) {
    final static __gshared public HandlerList!T getHandler() {
        if( handler_ is null ) {
            handler_ = new HandlerList!T();
        }
        return handler_;
    }
}

public class EventTemplate(T) : Event {
    mixin Eventable!T;
}

class TestEvent : EventTemplate!(TestEvent) {
    double x = 0.0;
}

TestEvent.getHandler() -> wont work.
June 20, 2013
On Thursday, 20 June 2013 at 00:20:36 UTC, Agustin wrote:
> On Wednesday, 19 June 2013 at 23:35:16 UTC, Ali Çehreli wrote:
>> On 06/19/2013 04:29 PM, Agustin wrote:
>>> Hello guys, my question is, its possible to write a mixin in a class,
>>> then if that class is inherited, the mixin will be written again instead
>>> of written the mixin again in the class child, for example:
>>>
>>> Class A(T)
>>> {
>>> mixin(WriteFunctionFor!(A));
>>> }
>>>
>>> Class B : A(B)
>>> {
>>>  ... -> mixin is written for B without need to write ("mixin(Write...))")
>>> }
>>>
>>> Class C : A(C)
>>> {
>>>  ... -> mixin is written for C without need to write ("mixin(Write...))")
>>> }
>>
>> Yes:
>>
>> import std.stdio;
>>
>> template WriteFunctionFor(T)
>> {
>>    T data;
>>
>>    void foo()
>>    {
>>        writefln("I am working with a %s.", T.stringof);
>>    }
>> }
>>
>> class A(T)
>> {
>>    mixin WriteFunctionFor!T;
>> }
>>
>> class B : A!B
>> {}
>>
>> class C : A!C
>> {}
>>
>> void main()
>> {
>>    auto b = new B();
>>    b.foo();
>>
>>    auto c = new C();
>>    c.foo();
>> }
>>
>> The output:
>>
>> I am working with a B.
>> I am working with a C.
>>
>> Ali
>
> Thanks!, now i'm trying to do that but its not working :(.
>
> template Eventable(T) {
>     final static __gshared public HandlerList!T getHandler() {
>         if( handler_ is null ) {
>             handler_ = new HandlerList!T();
>         }
>         return handler_;
>     }
> }
>
> public class EventTemplate(T) : Event {
>     mixin Eventable!T;
> }
>
> class TestEvent : EventTemplate!(TestEvent) {
>     double x = 0.0;
> }
>
> TestEvent.getHandler() -> wont work.

 public class EventTemplate(T) : Event {
     mixin Eventable!T;
     protected __gshared HandlerList!T handler_;
 }
June 20, 2013
On Wednesday, 19 June 2013 at 23:44:12 UTC, Jonathan M Davis wrote:
>
> Ah, you're right. That will work. I misread the question. I thought that he
> was asking whether mixins in the base class magically got mixed in again into
> the derived class, which they don't.
>
> - Jonathan M Davis

yeah, that's the "curiously recursive template pattern". The thing is that all these classes don't actually derive from a common base. The fact that they have a base class is only an implementation detail.

This trick is used a lot in C++, but in D, I really don't see what you get doing this over a simple template mixin (appart from not being able to have a "true" base class)...