digitalmars.D.learn - Using template mixin, with or without mixin ?
- biocyberman (19/19) Apr 07 2017 I want to use mixin to generate function in-place. In template
- =?UTF-8?Q?Ali_=c3=87ehreli?= (8/27) Apr 07 2017 The difference is that you can't use funcgen as a regular template:
- biocyberman (2/10) Apr 08 2017 Thanks for a very concise answer.
- Meta (24/39) Apr 08 2017 In addition to Ali's answer, mixin templates do their symbol
I want to use mixin to generate function in-place. In template declaration, I can see 'mixin' keyword is optional. Is it true? What is the difference and when I must use one way over another? This is my program: // This works with and without 'mixin' attribute. mixin template funcgen(T, U){ T func1(string pr2){ writeln("Func1: ", pr2); } U func2(string pr3){ writeln("Func2: ", pr3); } } int main(string[] args){ mixin funcgen!(void, void); func1("func1"); func2("func2"); return 0; }
Apr 07 2017
On 04/07/2017 04:47 PM, biocyberman wrote:I want to use mixin to generate function in-place. In template declaration, I can see 'mixin' keyword is optional. Is it true? What is the difference and when I must use one way over another? This is my program: // This works with and without 'mixin' attribute. mixin template funcgen(T, U){ T func1(string pr2){ writeln("Func1: ", pr2); } U func2(string pr3){ writeln("Func2: ", pr3); } } int main(string[] args){ mixin funcgen!(void, void); func1("func1"); func2("func2"); return 0; }The difference is that you can't use funcgen as a regular template: funcgen!(void, void); Error: template instance funcgen!(void, void) mixin templates are not regular templates I think it's good practice to use 'mixin template' if it's intended to be so. Ali
Apr 07 2017
On Friday, 7 April 2017 at 23:53:12 UTC, Ali Çehreli wrote:The difference is that you can't use funcgen as a regular template: funcgen!(void, void); Error: template instance funcgen!(void, void) mixin templates are not regular templates I think it's good practice to use 'mixin template' if it's intended to be so. AliThanks for a very concise answer.
Apr 08 2017
On Saturday, 8 April 2017 at 09:47:07 UTC, biocyberman wrote:On Friday, 7 April 2017 at 23:53:12 UTC, Ali Çehreli wrote:In addition to Ali's answer, mixin templates do their symbol looking at the instantiation site, while regular templates do it at the declaration site. Example: enum a = 0; template test1() { enum b1 = a; //Okay, a is in scope at the declaration site //enum c = d1; Error: undefined identifier d1 } mixin template test2() { enum b2 = a; //Okay, a is in scope at the declaration site enum c = d1; //Okay, d1 is in scope at the *instantiation* site //enum e = d2; Error: undefined identifier d2 } void main() { enum d1 = 0; //<--d1 is declared here mixin test1!(); mixin test2!(); //<--so it is in scope here enum d2 = 0; //d2 was not declared before test2 was mixed in //so it is not in scope for test2 }The difference is that you can't use funcgen as a regular template: funcgen!(void, void); Error: template instance funcgen!(void, void) mixin templates are not regular templates I think it's good practice to use 'mixin template' if it's intended to be so. AliThanks for a very concise answer.
Apr 08 2017
On 04/08/2017 11:59 PM, Meta wrote:enum a = 0; template test1() { enum b1 = a; //Okay, a is in scope at the declaration site //enum c = d1; Error: undefined identifier d1This line works just fine, actually. There's really no difference between a normal template and a mixin template when you use it in a mixin.} mixin template test2() { enum b2 = a; //Okay, a is in scope at the declaration site enum c = d1; //Okay, d1 is in scope at the *instantiation* site //enum e = d2; Error: undefined identifier d2 } void main() { enum d1 = 0; //<--d1 is declared here mixin test1!(); mixin test2!(); //<--so it is in scope here enum d2 = 0; //d2 was not declared before test2 was mixed in //so it is not in scope for test2 }
Apr 08 2017
On Saturday, 8 April 2017 at 22:37:18 UTC, ag0aep6g wrote:On 04/08/2017 11:59 PM, Meta wrote:Hmm, you're right, but this is not how it is supposed to behave according to the documentation. https://dlang.org/spec/template-mixin.htmlenum a = 0; template test1() { enum b1 = a; //Okay, a is in scope at the declaration site //enum c = d1; Error: undefined identifier d1This line works just fine, actually. There's really no difference between a normal template and a mixin template when you use it in a mixin.} mixin template test2() { enum b2 = a; //Okay, a is in scope at the declaration site enum c = d1; //Okay, d1 is in scope at the *instantiation* site //enum e = d2; Error: undefined identifier d2 } void main() { enum d1 = 0; //<--d1 is declared here mixin test1!(); mixin test2!(); //<--so it is in scope here enum d2 = 0; //d2 was not declared before test2 was mixed in //so it is not in scope for test2 }
Apr 08 2017
On 04/09/2017 07:44 AM, Meta wrote:On Saturday, 8 April 2017 at 22:37:18 UTC, ag0aep6g wrote:[...][...]This line works just fine, actually. There's really no difference between a normal template and a mixin template when you use it in a mixin.Hmm, you're right, but this is not how it is supposed to behave according to the documentation. https://dlang.org/spec/template-mixin.htmlThe most fitting sentence I can find there is this: "Unlike a template instantiation, a template mixin's body is evaluated within the scope where the mixin appears, not where the template declaration is defined." But that doesn't compare the different kinds of declarations. It compares the invocations: "template instantiation" vs "template mixin". A "template instantiation" is, of course, something like `foo!()`. But the definition of a "template mixin" [1] may be a bit surprising. `mixin bar!()` is a "template mixin". It isn't and doesn't contain a "template instantiation". It's an independent language construct. Also note that the spec says: "The MixinTemplateName refers to a TemplateDeclaration." That is, MixinTemplateName is not restricted to refer to a TemplateMixinDeclaration. Actually, being pedantic, the spec doesn't say that you can use the name of a TemplateMixinDeclaration. Seems to be a minor oversight. PR: https://github.com/dlang/dlang.org/pull/1627 [1] https://dlang.org/spec/template-mixin.html#TemplateMixin
Apr 09 2017