digitalmars.D.learn - Can someone explain how mixin is implemented?
- Matthew Ong (27/27) May 18 2011 Hi,
- Steven Schveighoffer (21/43) May 18 2011 There is a huge difference between #define and mixin. #define is a
- Matthew Ong (12/15) May 18 2011 Thanks for the attempt and sample code.
- Jonathan M Davis (14/32) May 18 2011 First off, template mixins and string mixins are different beasts. In on...
- Jacob Carlborg (9/41) May 18 2011 Template mixins are not exactly like copy and paste code.
- Matthew Ong (16/67) May 19 2011 Hi Jacob,
- Steven Schveighoffer (23/45) May 19 2011 Java does *not* use templates, they are generics. A generic seems like,...
- Matthew Ong (25/57) May 19 2011 According to Jonathan,
- Jacob Carlborg (25/50) May 19 2011 I can try to example by giving an example:
- Jesse Phillips (20/28) May 18 2011 I can see what you're trying for and it looks like you'll need string mi...
- Matthew Ong (11/39) May 19 2011 Hi Jesse,
- Matthew Ong (12/62) May 19 2011 Hi jesse,
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
On 5/18/2011 10:46 PM, Steven Schveighoffer wrote: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 Davisbut 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.
May 18 2011
On 2011-05-18 20:05, Jonathan M Davis 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. -- /Jacob CarlborgOn 5/18/2011 10:46 PM, Steven Schveighoffer wrote: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 Davisbut 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.
May 18 2011
On 5/19/2011 2:32 AM, Jacob Carlborg wrote:On 2011-05-18 20:05, Jonathan M Davis wrote:Hi Jacob, The last message confused me. Please clarify.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.On 5/18/2011 10:46 PM, Steven Schveighoffer wrote: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 Davisbut 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.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: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 JavaTemplate 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).Yes, it's a LinkedList with the type given as Object. -Steve
May 19 2011
On 5/19/2011 10:02 PM, Steven Schveighoffer wrote:On Thu, 19 May 2011 09:43:14 -0400, Matthew Ong <ongbp yahoo.com> wrote:According to Jonathan, In the case of template mixins, you're essentially copying and pasting code. Yes. Liked what you said, with optimization at compiled time. I am not trying to ask D to use JVM. (Please Note, that is why I choose D and also Go for the system level programming over C++ or Java JFFI.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).Can someone really say why this is a bad bad idea for memory with some automated plumbing being done like in ActiveX.The huge advantages of templates over generics are:Yes. I do agree that template are NOT exactly generics,1. The generated type can be fully optimized (footprint and code) for the given type parameters.Yes. All compiler from source to binary has some sort of binary optimization. That is a really good thing. Javac has also those feature. Please do as much optimization as D can be.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.That is a good good thing to have, it allows the runtime binary to be reduced in time where only the data type is different. I understand that Java has a JVM to do that but I believe similar thing has been also proven by ActiveX/Com+/DCom. I think they termed it Object Brokering.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 asBut perhaps some location about dynamic loading and unlaoding of DLL be part of D automatically. That is proven technology in the Linux Kernel for Device Driver module.-- Matthew Ong email: ongbp yahoo.comLinkedList<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
May 19 2011
On 2011-05-19 15:43, Matthew Ong wrote:On 5/19/2011 2:32 AM, Jacob Carlborg wrote:I can try to example by giving an example: template Foo (int i) { void foo () {} } class Bar { mixin Foo!(3); mixin Foo!(4); } The above code works and the two methods "foo" will not conflict. You can refer to them via the template: Foo!(3).foo; Second example: template Foo () { void foo (int i) {} } class Bar { mixin Foo; void foo () {} } If template mixins where like copy and paste the first example would result in an error. In the second example you would have two methods named "foo" overloading each other. But that's not what's happening.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.-- /Jacob Carlborg
May 19 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/19/2011 1:23 AM, Jesse Phillips wrote:Matthew Ong Wrote: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.comPerhaps 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 19 2011
On 5/19/2011 9:18 PM, Matthew Ong wrote:On 5/19/2011 1:23 AM, Jesse Phillips wrote: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.comMatthew Ong Wrote: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!!!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 19 2011