Jump to page: 1 2
Thread overview
Can someone explain how mixin is implemented?
May 18, 2011
Matthew Ong
May 18, 2011
Matthew Ong
May 18, 2011
Jonathan M Davis
May 18, 2011
Jacob Carlborg
May 19, 2011
Matthew Ong
May 19, 2011
Matthew Ong
May 19, 2011
Jacob Carlborg
May 18, 2011
Jesse Phillips
May 19, 2011
Matthew Ong
May 19, 2011
Matthew Ong
May 18, 2011
Hi,
From what I can see mixin in D is used in place of #define in C++(cool!!!). However, I do have a few question.

mixin with template does address some of this issue I supposed. That does allow me to define up to level of content of a class but is not class itself.

mixin template AType(T){ // but does not seems to allow me to inherit ClassC this level.
private:
   T value;
public:
   this(){...}
   void print(){...}
}

class ClassB : ClassC{ // ClassC Inheritance/Interface must only be done at this level?
   mixin AType!(string); // content
}

Perhaps I am missing something here. How can class level definition be part of the mixin?

Does mixin generate the same binary code as #define as inline code,which meant that same binary is repeated everywhere that macro is used?

Or does it make a linked to the in a centralized locations that allow binary sharing when it is the same typed T??


-- 
Matthew Ong
email: ongbp@yahoo.com

May 18, 2011
On Wed, 18 May 2011 09:45:56 -0400, Matthew Ong <ongbp@yahoo.com> wrote:

> Hi,
>  From what I can see mixin in D is used in place of #define in C++(cool!!!). However, I do have a few question.
>
> mixin with template does address some of this issue I supposed. That does allow me to define up to level of content of a class but is not class itself.
>
> mixin template AType(T){ // but does not seems to allow me to inherit ClassC this level.
> private:
>     T value;
> public:
>     this(){...}
>     void print(){...}
> }
>
> class ClassB : ClassC{ // ClassC Inheritance/Interface must only be done at this level?
>     mixin AType!(string); // content
> }
>
> Perhaps I am missing something here. How can class level definition be part of the mixin?
>
> Does mixin generate the same binary code as #define as inline code,which meant that same binary is repeated everywhere that macro is used?

There is a huge difference between #define and mixin.  #define is a preprocessed macro.  That means, before the compiler ever sees anything, the preprocessor blindly substitutes all the #defined symbols with their definitions.  This means, you can put any text (even not-grammar-correct code) into a #define

A mixin is parsed by the compiler, which means it must follow the grammar of the language.  You can't arbitrarily put mixins anywhere, they must be in places where mixins can be parsed.

I don't think you can mixin a base class, but you can do a string mixin to define the entire class.  This is not an easy thing to do, because you'd have to write the entire class as a string of text.

For instance (untested):

string inheritFromC(string classname, string classbodytemp)
{
  return "class " ~ classname ~ " : ClassC { mixin " ~ classbodytemp ~ ;}";
}

mixin(inheritFromC("ClassB", "AType!string"));

Note, I am *not* a mixin guru, so this might be totally bunk!  But I think it works.

-Steve
May 18, 2011
On 5/18/2011 10:46 PM, Steven Schveighoffer wrote:
> but you can do a string mixin to define the entire class.  This is not
> an easy thing to do, because you'd have to write the entire class as a
> string of text.
Thanks for the attempt and sample code.

Seen that script import somewhere before. Perhaps others would like to help.

Does mixin generate the same binary code as #define as inline code,which meant that same binary is repeated everywhere that macro is used?

Or does it make a linked to the in a centralized locations that allow binary sharing when it is the same typed T??

Do you have any idea? because the results is in dll/exe I cannot really tell. But someone that knows how the compiler works should be able to.

-- 
Matthew Ong
email: ongbp@yahoo.com

May 18, 2011
Matthew Ong Wrote:

> Perhaps I am missing something here. How can class level definition be part of the mixin?
> 
> Does mixin generate the same binary code as #define as inline code,which meant that same binary is repeated everywhere that macro is used?
> 
> Or does it make a linked to the in a centralized locations that allow binary sharing when it is the same typed T??

I can see what you're trying for and it looks like you'll need string mixins to make it happen.

Mixing is similar to #define in that it does string substitution, but it is unlike #define in that valid D is required declaration and call. You'll have to modify this with string  mixins (I'm surprised it compiles excluding the non-existence of ClassB):

mixin template AType(alias T, U, alias V){class T : ClassC {
private:
    U value;
public:
    this(){}
    void print(){}
        mixin V;
}
}

class ClassC {}

mixin template btype() {
    void someFunction() {};
}

mixin AType!("ClassB", string, btype);

void main() {
    ClassC r = new ClassB();
}


May 18, 2011
> On 5/18/2011 10:46 PM, Steven Schveighoffer wrote:
> > but you can do a string mixin to define the entire class. This is not an easy thing to do, because you'd have to write the entire class as a string of text.
> 
> Thanks for the attempt and sample code.
> 
> Seen that script import somewhere before. Perhaps others would like to help.
> 
> Does mixin generate the same binary code as #define as inline code,which meant that same binary is repeated everywhere that macro is used?
> 
> Or does it make a linked to the in a centralized locations that allow binary sharing when it is the same typed T??
> 
> Do you have any idea? because the results is in dll/exe I cannot really tell. But someone that knows how the compiler works should be able to.

First off, template mixins and string mixins are different beasts. In one case, you're mixing in a template. In the other, you're mixing in strings of code. Template mixins must be valid code even without being mixed in. String mixins have to result in valid code, but they're strings so they can hold anything. Both types of mixins, however, have to be explicitly mixed in (as opposed to the textual replacement that #defines do). In the case of template mixins, you're essentially copying and pasting code. In the case of string mixins, you're creating strings that are the code, so it's pretty much just like if you typed the code in there yourself except that the compiler is putting it in there for you instead, allowing you to use functions to generate code and save you from having to type it all. There is no linking involved in mixins. It's not shared. You're generating code and inserting it where you used the mixin statement.

- Jonathan M Davis
May 18, 2011
On 2011-05-18 20:05, Jonathan M Davis wrote:
>> On 5/18/2011 10:46 PM, Steven Schveighoffer wrote:
>>> but you can do a string mixin to define the entire class. This is not
>>> an easy thing to do, because you'd have to write the entire class as a
>>> string of text.
>>
>> Thanks for the attempt and sample code.
>>
>> Seen that script import somewhere before. Perhaps others would like to
>> help.
>>
>> Does mixin generate the same binary code as #define as inline code,which
>> meant that same binary is repeated everywhere that macro is used?
>>
>> Or does it make a linked to the in a centralized locations that allow
>> binary sharing when it is the same typed T??
>>
>> Do you have any idea? because the results is in dll/exe I cannot really
>> tell. But someone that knows how the compiler works should be able to.
>
> First off, template mixins and string mixins are different beasts. In one
> case, you're mixing in a template. In the other, you're mixing in strings of
> code. Template mixins must be valid code even without being mixed in. String
> mixins have to result in valid code, but they're strings so they can hold
> anything. Both types of mixins, however, have to be explicitly mixed in (as
> opposed to the textual replacement that #defines do). In the case of template
> mixins, you're essentially copying and pasting code. In the case of string
> mixins, you're creating strings that are the code, so it's pretty much just
> like if you typed the code in there yourself except that the compiler is
> putting it in there for you instead, allowing you to use functions to generate
> code and save you from having to type it all. There is no linking involved in
> mixins. It's not shared. You're generating code and inserting it where you
> used the mixin statement.
>
> - Jonathan M Davis

Template mixins are not exactly like copy and paste code.

* You can mixin the same template, at the same location, twice, taking different parameters

* Mixed in methods doesn't overload on existing methods in the scope where the mixin is used

I think all this is due to mixins being mixed-in in it's own scope.

-- 
/Jacob Carlborg
May 19, 2011
On 5/19/2011 1:23 AM, Jesse Phillips wrote:
> Matthew Ong Wrote:
>
>> Perhaps I am missing something here. How can class level definition be
>> part of the mixin?
>>
>> Does mixin generate the same binary code as #define as inline code,which
>> meant that same binary is repeated everywhere that macro is used?
>>
>> Or does it make a linked to the in a centralized locations that allow
>> binary sharing when it is the same typed T??
>
> I can see what you're trying for and it looks like you'll need string mixins to make it happen.
>
> Mixing is similar to #define in that it does string substitution, but it is unlike #define in that valid D is required declaration and call. You'll have to modify this with string  mixins (I'm surprised it compiles excluding the non-existence of ClassB):
>
> mixin template AType(alias T, U, alias V){class T : ClassC {
> private:
>      U value;
> public:
>      this(){}
>      void print(){}
>          mixin V;
> }
> }
>
> class ClassC {}
>
> mixin template btype() {
>      void someFunction() {};
> }
>
> mixin AType!("ClassB", string, btype);
>
> void main() {
>      ClassC r = new ClassB();
> }
>
>
Hi Jesse,
 That is cool. Useful example like this should be within the documentation also. That helped me a lot. Now, I do not have to be concerned that the class level mixin usage class missed out the inheritance and also the implementation.

This pattern is very useful for flattening the Object inheritance tree.
D is cool!!!

-- 
Matthew Ong
email: ongbp@yahoo.com

May 19, 2011
On 5/19/2011 9:18 PM, Matthew Ong wrote:
> On 5/19/2011 1:23 AM, Jesse Phillips wrote:
>> Matthew Ong Wrote:
>>
>>> Perhaps I am missing something here. How can class level definition be
>>> part of the mixin?
>>>
>>> Does mixin generate the same binary code as #define as inline code,which
>>> meant that same binary is repeated everywhere that macro is used?
>>>
>>> Or does it make a linked to the in a centralized locations that allow
>>> binary sharing when it is the same typed T??
>>
>> I can see what you're trying for and it looks like you'll need string
>> mixins to make it happen.
>>
>> Mixing is similar to #define in that it does string substitution, but
>> it is unlike #define in that valid D is required declaration and call.
>> You'll have to modify this with string mixins (I'm surprised it
>> compiles excluding the non-existence of ClassB):
>>
>> mixin template AType(alias T, U, alias V){class T : ClassC {
>> private:
>> U value;
>> public:
>> this(){}
>> void print(){}
>> mixin V;
>> }
>> }
>>
>> class ClassC {}
>>
>> mixin template btype() {
>> void someFunction() {};
>> }
>>
>> mixin AType!("ClassB", string, btype);
>>
>> void main() {
>> ClassC r = new ClassB();
>> }
>>
>>
> Hi Jesse,
> That is cool. Useful example like this should be within the
> documentation also. That helped me a lot. Now, I do not have to be
> concerned that the class level mixin usage class missed out the
> inheritance and also the implementation.
>
> This pattern is very useful for flattening the Object inheritance tree.
> D is cool!!!
>
Hi jesse,

I obtain error from: ClassC r = new ClassB();

src\main.d(27): Error: undefined identifier ClassB, did you mean class ClassC?
src\main.d(27): Error: ClassB is used as a type

Somehow this information is not known to the compiler....
mixin AType!("ClassB", string, btype);

Please help.

-- 
Matthew Ong
email: ongbp@yahoo.com

May 19, 2011
On 5/19/2011 2:32 AM, Jacob Carlborg wrote:
> On 2011-05-18 20:05, Jonathan M Davis wrote:
>>> On 5/18/2011 10:46 PM, Steven Schveighoffer wrote:
>>>> but you can do a string mixin to define the entire class. This is not
>>>> an easy thing to do, because you'd have to write the entire class as a
>>>> string of text.
>>>
>>> Thanks for the attempt and sample code.
>>>
>>> Seen that script import somewhere before. Perhaps others would like to
>>> help.
>>>
>>> Does mixin generate the same binary code as #define as inline code,which
>>> meant that same binary is repeated everywhere that macro is used?
>>>
>>> Or does it make a linked to the in a centralized locations that allow
>>> binary sharing when it is the same typed T??
>>>
>>> Do you have any idea? because the results is in dll/exe I cannot really
>>> tell. But someone that knows how the compiler works should be able to.
>>
>> First off, template mixins and string mixins are different beasts. In one
>> case, you're mixing in a template. In the other, you're mixing in
>> strings of
>> code. Template mixins must be valid code even without being mixed in.
>> String
>> mixins have to result in valid code, but they're strings so they can hold
>> anything. Both types of mixins, however, have to be explicitly mixed
>> in (as
>> opposed to the textual replacement that #defines do). In the case of
>> template
>> mixins, you're essentially copying and pasting code. In the case of
>> string
>> mixins, you're creating strings that are the code, so it's pretty much
>> just
>> like if you typed the code in there yourself except that the compiler is
>> putting it in there for you instead, allowing you to use functions to
>> generate
>> code and save you from having to type it all. There is no linking
>> involved in
>> mixins. It's not shared. You're generating code and inserting it where
>> you
>> used the mixin statement.
>>
>> - Jonathan M Davis
>
> Template mixins are not exactly like copy and paste code.
>
> * You can mixin the same template, at the same location, twice, taking
> different parameters
>
> * Mixed in methods doesn't overload on existing methods in the scope
> where the mixin is used
>
> I think all this is due to mixins being mixed-in in it's own scope.
>
Hi Jacob,

The last message confused me. Please clarify.
>not exactly like copy and paste code.
Ok...So, does it meant that the compiler share some sort of binary?

In java using template, the same LinkedList binary is shared for both String class type and also Integer class type.

LinkedList<String> list=new LinkedList<String>();
LinkedList<Integer> list=new LinkedList<Integer>();

// Can also apply for Account.
LinkedList<Account> list=new LinkedList<Account>();


But there is a single LinkedList Class File(single binary).

mixin template does seemed to be better than #define (uncheck by compiler directly) it can be any text. M4 is a tool exactly that purpose.



-- 
Matthew Ong
email: ongbp@yahoo.com

May 19, 2011
On Thu, 19 May 2011 09:43:14 -0400, Matthew Ong <ongbp@yahoo.com> wrote:

> On 5/19/2011 2:32 AM, Jacob Carlborg wrote:
>> Template mixins are not exactly like copy and paste code.
>>
>> * You can mixin the same template, at the same location, twice, taking
>> different parameters
>>
>> * Mixed in methods doesn't overload on existing methods in the scope
>> where the mixin is used
>>
>> I think all this is due to mixins being mixed-in in it's own scope.
>>
> Hi Jacob,
>
> The last message confused me. Please clarify.
>  >not exactly like copy and paste code.
> Ok...So, does it meant that the compiler share some sort of binary?
>
> In java using template, the same LinkedList binary is shared for both String class type and also Integer class type.

Java does *not* use templates, they are generics.  A generic seems like, but is vastly different from a template.

A template *re-generates* the code as if you substituted the type for the given template parameter.

A generic generates one object code file with a base class, and then simply enforces the type constraints at compile time when *using* the generic.  Under the hood, the generic is compiled with the base class as the given type.  It probably avoids doing any type checking at runtime as well (since it knows the compiler will check the type for it).

The huge advantages of templates over generics are:

1. The generated type can be fully optimized (footprint and code) for the given type parameters.
2. You can execute different code paths depending on the parameter types.
3. You do not have to select a common base class/interface for a group of types.  That is, you can select any set of types that will work with your template.  With generics, all possible types need to have a common base.
4. Boxing/unboxing is not necessary for non-object types.

The advantage of generics are that you only have one compiled version.  This is actually very important for bytecode-based languages such as Java and C#.

> LinkedList<String> list=new LinkedList<String>();
> LinkedList<Integer> list=new LinkedList<Integer>();
>
> // Can also apply for Account.
> LinkedList<Account> list=new LinkedList<Account>();
>
>
> But there is a single LinkedList Class File(single binary).

Yes, it's a LinkedList with the type given as Object.

-Steve
« First   ‹ Prev
1 2