Jump to page: 1 2
Thread overview
Mixins & init code, others
May 18, 2004
Mike Swieton
May 18, 2004
fred
May 18, 2004
Walter
May 18, 2004
Andy Friesen
May 18, 2004
Roel Mathys
May 18, 2004
Roel Mathys
May 18, 2004
Roel Mathys
May 18, 2004
Vathix
May 18, 2004
Russ Lewis
May 19, 2004
Kevin Bealer
May 18, 2004
Michael Coupland
May 18, 2004
Walter
May 18, 2004
Ben Hinkle
May 18, 2004
Walter
May 18, 2004
Norbert Nemec
May 18, 2004
Norbert Nemec
May 18, 2004
Mike Swieton
May 18, 2004
Norbert Nemec
May 18, 2004
It would be extremely useful to have mixins have constructors for some initialization, i.e. a constructor. Has anyone figured out how to do this? I've come up with some cheap hack solutions, but nothing that really works well. I'd settle for "mixin ctor code is lexically composed with each ctor of the mixed class". But a little ability for initializing the data would be extremely handy.

A second, and most likely more important item: mixins need to support invariants. The above is much less important if I can use an invariant to inforce that a manually called init method has been called. This also should not be complex: a lexical composition would work perfectly fine (although scoping rules would have to be determined).

Has anyone thought about this? The lack of ctors and invariants I think somewhat limits the utility of mixing classes, because one cannot provide good initialization of data in any way.

Mike Swieton
__
Computer Science is the only discipline in which we view adding a new wing to
a building as being maintenance.
	- Jim Horning

May 18, 2004
"Mike Swieton" <mike@swieton.net> wrote in message news:pan.2004.05.18.02.44.03.517824@swieton.net...
> It would be extremely useful to have mixins have constructors for some initialization, i.e. a constructor. Has anyone figured out how to do this? I've come up with some cheap hack solutions, but nothing that really works well. I'd settle for "mixin ctor code is lexically composed with each ctor of the mixed class". But a little ability for initializing the data would be extremely handy.

How about something like this ??

class Part
{
    this(int param) { v = param; }
    int    Value() { return v; }
private:
    int    v;
}

template Construct!( T, alias param )
{
    T part = new T(param);
}

class Some
{
    this(int param) { x = param; }
private:
    int    x;
    mixin Construct!( Part, x*2 )    part;
}

int main()
{
    Some some(5);
    return some.part.Value(); // will return 10
}

>
> A second, and most likely more important item: mixins need to support invariants. The above is much less important if I can use an invariant to inforce that a manually called init method has been called. This also should not be complex: a lexical composition would work perfectly fine (although scoping rules would have to be determined).
>
> Has anyone thought about this? The lack of ctors and invariants I think somewhat limits the utility of mixing classes, because one cannot provide good initialization of data in any way.

Have you got any code that could explain this further ?

cheers fred


May 18, 2004
Actually, you can mix in constructors. Just put a 'this' method in the template.

"Mike Swieton" <mike@swieton.net> wrote in message news:pan.2004.05.18.02.44.03.517824@swieton.net...
> It would be extremely useful to have mixins have constructors for some initialization, i.e. a constructor. Has anyone figured out how to do this? I've come up with some cheap hack solutions, but nothing that really works well. I'd settle for "mixin ctor code is lexically composed with each ctor
of
> the mixed class". But a little ability for initializing the data would be extremely handy.
>
> A second, and most likely more important item: mixins need to support invariants. The above is much less important if I can use an invariant to inforce that a manually called init method has been called. This also
should
> not be complex: a lexical composition would work perfectly fine (although scoping rules would have to be determined).
>
> Has anyone thought about this? The lack of ctors and invariants I think somewhat limits the utility of mixing classes, because one cannot provide
good
> initialization of data in any way.
>
> Mike Swieton
> __
> Computer Science is the only discipline in which we view adding a new wing
to
> a building as being maintenance.
> - Jim Horning
>


May 18, 2004
Walter wrote:
> Actually, you can mix in constructors. Just put a 'this' method in the
> template.

I think he means something like this: (which does not work)

    template Mix1() {
        this() { printf("mix1\n"); }
    }
    template Mix2() {
        this() { printf("Mix2!\n"); }
    }

    class Bar {
        mixin Mix1;
        mixin Mix2;
    }

    int main() {
        Bar bar = new Bar();
        return 0;
    }

I think this is part of the can of worms that Matthew was talking about* when he suggested not allowing mixins to add attributes.  Not only do mixins require constructors, they need to have invariants as well.

* here: http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/133

 -- andy
May 18, 2004
Walter wrote:
> Actually, you can mix in constructors. Just put a 'this' method in the
> template.

That still doesn't work very well if your goal is to guarantee that your constructor is executed. (A handy thing to have happen...) I was just playing around with mixins, and the following code demonstrates the problem:

----------

template MixVar()
{
	this() { mixed_var = 1;	}
	int mixed_var;
}

class MixTarg
{
	this( ) { targ_var = 2; }
	int targ_var;
	mixin MixVar;

	void print() { printf( "(%d, %d)", targ_var, mixed_var ); }
}

int main( char[][] args )
{
	MixTarg test = new MixTarg();
	test.print();
	return 0;	
}

----------

The output is:
	(2, 0)
Rather than the (expected? hoped-for?):
	(2, 1)

So I guess the question is, is there a way to have the mixin's constructor called /in addition to/ whatever constructor is called for the base class. (The current way you can merely supply new constructors,
and (as this example shows) they won't override any existing constructors of identical signature.

	Michael
May 18, 2004
Andy Friesen wrote:

> Walter wrote:
> 
>> Actually, you can mix in constructors. Just put a 'this' method in the
>> template.
> 
> 
> I think he means something like this: (which does not work)
> 
>     template Mix1() {
>         this() { printf("mix1\n"); }
>     }
>     template Mix2() {
>         this() { printf("Mix2!\n"); }
>     }
> 
>     class Bar {
>         mixin Mix1;
>         mixin Mix2;
>     }
> 
>     int main() {
>         Bar bar = new Bar();
>         return 0;
>     }
> 
> I think this is part of the can of worms that Matthew was talking about* when he suggested not allowing mixins to add attributes.  Not only do mixins require constructors, they need to have invariants as well.
> 
> * here: http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/133
> 
>  -- andy

this does work,

template Mix1() {
    this() { printf("mix1\n"); }
}
template Mix2() {
    this(int x) { printf("Mix2!\n"); }
}

class Bar
{
    mixin Mix1;
    mixin Mix2;
}

int main() {
    Bar bar = new Bar();
    return 0;
}

mayb it would be better if a this defined this way somehow magically attaches itself to the original ctor,

bye,
roel

ps: the only place I like magic is in a good book



May 18, 2004
Roel Mathys wrote:

> Andy Friesen wrote:
> 
>> Walter wrote:
>>
>>> Actually, you can mix in constructors. Just put a 'this' method in the
>>> template.
>>
>>
>>
>> I think he means something like this: (which does not work)
>>
>>     template Mix1() {
>>         this() { printf("mix1\n"); }
>>     }
>>     template Mix2() {
>>         this() { printf("Mix2!\n"); }
>>     }
>>
>>     class Bar {
>>         mixin Mix1;
>>         mixin Mix2;
>>     }
>>
>>     int main() {
>>         Bar bar = new Bar();
>>         return 0;
>>     }
>>
>> I think this is part of the can of worms that Matthew was talking about* when he suggested not allowing mixins to add attributes.  Not only do mixins require constructors, they need to have invariants as well.
>>
>> * here: http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/133
>>
>>  -- andy
> 
> 
> this does work,
> 
> template Mix1() {
>     this() { printf("mix1\n"); }
> }
> template Mix2() {
>     this(int x) { printf("Mix2!\n"); }
> }
> 
> class Bar
> {
>     mixin Mix1;
>     mixin Mix2;
> }
> 
> int main() {
>     Bar bar = new Bar();
>     return 0;
> }
> 
> mayb it would be better if a this defined this way somehow magically attaches itself to the original ctor,
> 
> bye,
> roel
> 
> ps: the only place I like magic is in a good book
> 
> 
> 

something like this, please don't flame for abusing some feature :-)

template Mix1() {
    void Mix1() { printf("mix1\n"); }
}
template Mix2() {
    void Mix2() { printf("Mix2!\n"); }
}

class Bar
{
    int myx;

    this()
    in  { mixin Mix1; Mix1(); }
    out { mixin Mix2; Mix2(); }
    body { myx = 15; }

}

int main() {
    Bar bar = new Bar();
    return 0;
}


bye,
roel
May 18, 2004
Roel Mathys wrote:

> Roel Mathys wrote:
> 
>> Andy Friesen wrote:
>>
>>> Walter wrote:
>>>
>>>> Actually, you can mix in constructors. Just put a 'this' method in the
>>>> template.
>>>
>>>
>>>
>>>
>>> I think he means something like this: (which does not work)
>>>
>>>     template Mix1() {
>>>         this() { printf("mix1\n"); }
>>>     }
>>>     template Mix2() {
>>>         this() { printf("Mix2!\n"); }
>>>     }
>>>
>>>     class Bar {
>>>         mixin Mix1;
>>>         mixin Mix2;
>>>     }
>>>
>>>     int main() {
>>>         Bar bar = new Bar();
>>>         return 0;
>>>     }
>>>
>>> I think this is part of the can of worms that Matthew was talking about* when he suggested not allowing mixins to add attributes.  Not only do mixins require constructors, they need to have invariants as well.
>>>
>>> * here: http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/133
>>>
>>>  -- andy
>>
>>
>>
>> this does work,
>>
>> template Mix1() {
>>     this() { printf("mix1\n"); }
>> }
>> template Mix2() {
>>     this(int x) { printf("Mix2!\n"); }
>> }
>>
>> class Bar
>> {
>>     mixin Mix1;
>>     mixin Mix2;
>> }
>>
>> int main() {
>>     Bar bar = new Bar();
>>     return 0;
>> }
>>
>> mayb it would be better if a this defined this way somehow magically attaches itself to the original ctor,
>>
>> bye,
>> roel
>>
>> ps: the only place I like magic is in a good book
>>
>>
>>
> 
> something like this, please don't flame for abusing some feature :-)
> 
> template Mix1() {
>     void Mix1() { printf("mix1\n"); }
> }
> template Mix2() {
>     void Mix2() { printf("Mix2!\n"); }
> }
> 
> class Bar
> {
>     int myx;
> 
>     this()
>     in  { mixin Mix1; Mix1(); }
>     out { mixin Mix2; Mix2(); }
>     body { myx = 15; }
> 
> }
> 
> int main() {
>     Bar bar = new Bar();
>     return 0;
> }
> 
> 
> bye,
> roel

apparantly, the mixin's must be directly in the scope of class, then you  can access members of the class

bye,
roel

----------------------------------------------------

template Mix1() { void Mix1() { myx = 1; }}
template Mix2() { void Mix2() { myx = 2; }}

class Bar
{
    int myx;

    mixin Mix1;
    mixin Mix2;

    this()
    in  { Mix1(); }
    out {  Mix2(); }
    body { myx = 15; }
}

int main() {
    Bar bar = new Bar();

    printf("myx = %d\n",bar.myx);
    return 0;
}

May 18, 2004
"Andy Friesen" <andy@ikagames.com> wrote in message news:c8c76s$2cvn$1@digitaldaemon.com...
> Walter wrote:
> > Actually, you can mix in constructors. Just put a 'this' method in the template.
>
> I think he means something like this: (which does not work)
>
>      template Mix1() {
>          this() { printf("mix1\n"); }
>      }
>      template Mix2() {
>          this() { printf("Mix2!\n"); }
>      }
>
>      class Bar {
>          mixin Mix1;
>          mixin Mix2;
>      }
>
>      int main() {
>          Bar bar = new Bar();
>          return 0;
>      }
>
> I think this is part of the can of worms that Matthew was talking about* when he suggested not allowing mixins to add attributes.  Not only do mixins require constructors, they need to have invariants as well.
>
> * here: http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/133
>
>   -- andy


How about constructors without parameter lists are implicitly called in order (as well as destructors), and if they take parameters, you have to have your constructor call them. Like this:


template Mix1()
{
   this() { printf("mix1\n"); }
}
template Mix2(int stuff)
{
   // Note the parameter list.
   this(int stuff) { printf("Mix2!\n"); }
   ~this() { /* stuff */ }
}

class Bar
{
   mixin Mix1;
   mixin Mix2;

   this()
   {
      // Mix1.this() // Implied.
      Mix2.this(4); // Required.
   }

   // ~this() { Mix2.~this(); } // Implied, or implicitly added to the end
of an existing destructor.
}


If you have a long complicated mixin like  Foo!(Stuff!(a, b, c!(d, e),
f!(etc)))  then just alias it.  aliasname.this(...). Or if it has a mixin
identifier then you can just use that name. Constructors aren't like normal
functions, you can't mix them in like a regular function because all
initializations need to occur.


May 18, 2004
"Michael Coupland" <mcoupland@hmc.edu> wrote in message news:c8c8dp$2f2v$1@digitaldaemon.com...
> Walter wrote:
> > Actually, you can mix in constructors. Just put a 'this' method in the template.
>
> That still doesn't work very well if your goal is to guarantee that your constructor is executed. (A handy thing to have happen...) I was just playing around with mixins, and the following code demonstrates the
problem:
>
> ----------
>
> template MixVar()
> {
> this() { mixed_var = 1; }
> int mixed_var;
> }
>
> class MixTarg
> {
> this( ) { targ_var = 2; }
> int targ_var;
> mixin MixVar;
>
> void print() { printf( "(%d, %d)", targ_var, mixed_var ); }
> }
>
> int main( char[][] args )
> {
> MixTarg test = new MixTarg();
> test.print();
> return 0;
> }
>
> ----------
>
> The output is:
> (2, 0)
> Rather than the (expected? hoped-for?):
> (2, 1)
>
> So I guess the question is, is there a way to have the mixin's constructor called /in addition to/ whatever constructor is called for the base class. (The current way you can merely supply new constructors, and (as this example shows) they won't override any existing constructors of identical signature.

What is happening here is any declarations in the current scope *override* declarations in a mixin scope when looking at it from outside the mixin. The idea is to have a generic version in the mixin, and perhaps a customized version to override it. Mixins aren't classes or structs. They're merely a list of declarations that acquire meaning *after* they are mixed in, and they take on meaning based on where they are mixed in, i.e. becoming struct members, class members, local variables, etc.


« First   ‹ Prev
1 2