digitalmars.D.learn - Mixin operator 'if' directly
- Andrey (5/12) Dec 19 2018 When I try to compile it, I get:
- rikki cattermole (1/1) Dec 19 2018 Mixin templates don't work on statements only declarations like structs.
- bauss (10/22) Dec 19 2018 What you want to use is "static if".
- bauss (5/29) Dec 19 2018 That's assuming that it's compile-time data though.
- Neia Neutuladh (15/21) Dec 19 2018 Or while instantiating it:
- bauss (4/25) Dec 20 2018 That's a genius hack.
- H. S. Teoh (42/60) Dec 20 2018 Me too! This is awesome! This basically lets you insert arbitrary code
- bauss (6/16) Dec 20 2018 I have so many places where I created a function manually using
- Michelle Long (37/98) Dec 21 2018 Note that it even captures locals:
- Timoses (14/29) Dec 21 2018 Awesome hack!
- Michelle Long (18/49) Dec 21 2018 Yep, except they will probably disable it in some way.
- Nicholas Wilson (2/33) Dec 22 2018 https://issues.dlang.org/show_bug.cgi?id=19506
- bauss (22/35) Dec 22 2018 I think this is the closest we can come to it:
- Basile B. (10/49) Dec 22 2018 One more line can be saved using a lambda to wrap the alias:
Hi, Here is a template mixin:mixin template create(alias input, uint index, alias data) { if(input.length < index) return; // ... some code }When I try to compile it, I get:Error: declaration expected, not ifIs it possible to mixin operator 'if' directly inside my template mixin?
Dec 19 2018
Mixin templates don't work on statements only declarations like structs.
Dec 19 2018
On Wednesday, 19 December 2018 at 13:37:17 UTC, Andrey wrote:Hi, Here is a template mixin:What you want to use is "static if". The correct way to do the above would be this: mixin template create(alias input, uint index, alias data) { static if(input.length >= index) // Reversed the logic. { // ... some code } }mixin template create(alias input, uint index, alias data) { if(input.length < index) return; // ... some code }When I try to compile it, I get:Error: declaration expected, not ifIs it possible to mixin operator 'if' directly inside my template mixin?
Dec 19 2018
On Wednesday, 19 December 2018 at 15:09:47 UTC, bauss wrote:On Wednesday, 19 December 2018 at 13:37:17 UTC, Andrey wrote:That's assuming that it's compile-time data though. If not then you can't do what you want to do. What you can do is wrap it in a function in the mixin template which you just call after instantiating it.Hi, Here is a template mixin:What you want to use is "static if". The correct way to do the above would be this: mixin template create(alias input, uint index, alias data) { static if(input.length >= index) // Reversed the logic. { // ... some code } }mixin template create(alias input, uint index, alias data) { if(input.length < index) return; // ... some code }When I try to compile it, I get:Error: declaration expected, not ifIs it possible to mixin operator 'if' directly inside my template mixin?
Dec 19 2018
On Wed, 19 Dec 2018 15:12:14 +0000, bauss wrote:That's assuming that it's compile-time data though. If not then you can't do what you want to do. What you can do is wrap it in a function in the mixin template which you just call after instantiating it.Or while instantiating it: mixin template foo() { int _ignoreme() { if (readln.strip == "abort") throw new AbortException; return 1; } int _alsoIgnoreMe = _ignoreme(); } void main() { mixin foo; }
Dec 19 2018
On Wednesday, 19 December 2018 at 15:40:50 UTC, Neia Neutuladh wrote:On Wed, 19 Dec 2018 15:12:14 +0000, bauss wrote:That's a genius hack. I have to adapt this!That's assuming that it's compile-time data though. If not then you can't do what you want to do. What you can do is wrap it in a function in the mixin template which you just call after instantiating it.Or while instantiating it: mixin template foo() { int _ignoreme() { if (readln.strip == "abort") throw new AbortException; return 1; } int _alsoIgnoreMe = _ignoreme(); } void main() { mixin foo; }
Dec 20 2018
On Thu, Dec 20, 2018 at 11:04:19AM +0000, bauss via Digitalmars-d-learn wrote:On Wednesday, 19 December 2018 at 15:40:50 UTC, Neia Neutuladh wrote:[...]Me too! This is awesome! This basically lets you insert arbitrary code via mixin templates with essentially no restrictions! You can even reuse the same ignore-identifiers in multiple instantiations of the same template, e.g.: import std.stdio; mixin template CodeMixin(int i) { int _impl() { static if (i == 0) { writeln("Haha, we inserted code via declarations!"); return int.init; } else static if (i == 1) { writeln("Well whaddya know, we can do multiple mixins!"); return int.init; } else static assert(0); } int _impl2 = _impl(); } void main() { writeln("Does it respect order?"); mixin CodeMixin!0; writeln("I should think so! But you never know..."); mixin CodeMixin!1; writeln("Wow, can we really do multiple mixins of this sort?"); } The output is: Does it respect order? Haha, we inserted code via declarations! I should think so! But you never know... Well whaddya know, we can do multiple mixins! Wow, can we really do multiple mixins of this sort? T -- If I were two-faced, would I be wearing this one? -- Abraham Lincolnmixin template foo() { int _ignoreme() { if (readln.strip == "abort") throw new AbortException; return 1; } int _alsoIgnoreMe = _ignoreme(); } void main() { mixin foo; }That's a genius hack. I have to adapt this!
Dec 20 2018
On Thursday, 20 December 2018 at 16:23:39 UTC, H. S. Teoh wrote:On Thu, Dec 20, 2018 at 11:04:19AM +0000, bauss via Digitalmars-d-learn wrote:I have so many places where I created a function manually using mixin template, that I then call afterwards. I can save so many manual function calls, allowing for easier maintenance! I have no idea why I've never thought about that before.[...][...][...]Me too! This is awesome! This basically lets you insert arbitrary code via mixin templates with essentially no restrictions! You can even reuse the same ignore-identifiers in multiple instantiations of the same template, e.g.: [...]
Dec 20 2018
On Thursday, 20 December 2018 at 16:23:39 UTC, H. S. Teoh wrote:On Thu, Dec 20, 2018 at 11:04:19AM +0000, bauss via Digitalmars-d-learn wrote:Note that it even captures locals: import std.stdio, std.conv; mixin template CodeMixin(int i) { int _impl() { static if (i == 0) { writeln("Haha, we inserted code via declarations! - " ~ to!string(x)); return int.init; } else static if (i == 1) { writeln("Well whaddya know, we can do multiple mixins! - " ~ to!string(x)); return int.init; } else static assert(0); } int _impl2 = _impl(); } void main() { int x = 3; writeln("Does it respect order?"); mixin CodeMixin!0; writeln("I should think so! But you never know..."); x = 4; mixin CodeMixin!1; writeln("Wow, can we really do multiple mixins of this sort?"); getchar(); } Seems like it could be used to replace a lot of string mixins so that real debugging could take place along with CT error checking, etc.On Wednesday, 19 December 2018 at 15:40:50 UTC, Neia Neutuladh wrote:[...]Me too! This is awesome! This basically lets you insert arbitrary code via mixin templates with essentially no restrictions! You can even reuse the same ignore-identifiers in multiple instantiations of the same template, e.g.: import std.stdio; mixin template CodeMixin(int i) { int _impl() { static if (i == 0) { writeln("Haha, we inserted code via declarations!"); return int.init; } else static if (i == 1) { writeln("Well whaddya know, we can do multiple mixins!"); return int.init; } else static assert(0); } int _impl2 = _impl(); } void main() { writeln("Does it respect order?"); mixin CodeMixin!0; writeln("I should think so! But you never know..."); mixin CodeMixin!1; writeln("Wow, can we really do multiple mixins of this sort?"); } The output is: Does it respect order? Haha, we inserted code via declarations! I should think so! But you never know... Well whaddya know, we can do multiple mixins! Wow, can we really do multiple mixins of this sort? Tmixin template foo() { int _ignoreme() { if (readln.strip == "abort") throw new AbortException; return 1; } int _alsoIgnoreMe = _ignoreme(); } void main() { mixin foo; }That's a genius hack. I have to adapt this!
Dec 21 2018
On Wednesday, 19 December 2018 at 15:40:50 UTC, Neia Neutuladh wrote:On Wed, 19 Dec 2018 15:12:14 +0000, bauss wrote: Or while instantiating it: mixin template foo() { int _ignoreme() { if (readln.strip == "abort") throw new AbortException; return 1; } int _alsoIgnoreMe = _ignoreme(); } void main() { mixin foo; }Awesome hack! Being a hack, it would be even nicer if it worked ouf of the box: mixin template foo(bool b) { int _impl() { writeln(b); return int.init; } int _ipml2 = _impl(); } vs mixin template foo(bool b) { writeln(b); }
Dec 21 2018
On Saturday, 22 December 2018 at 03:44:09 UTC, Timoses wrote:On Wednesday, 19 December 2018 at 15:40:50 UTC, Neia Neutuladh wrote:Yep, except they will probably disable it in some way. Surely though a template could be created that does all the work. Just pass an lambda in to a template. mixin template Code(alias f) { int _impl2 = (() { f(); return int.init; })(); } mixin Code!(() { writeln("Haha, we inserted code via declarations!");}); So now you can do mixin template foo(bool b) { mixin Code!(() { writeln(b); }); } If it could be made robust, maybe it would be effective. One still can't insert arbitrary code though. So it is not as useful as it looks but still gets over the arbitrary restriction.On Wed, 19 Dec 2018 15:12:14 +0000, bauss wrote: Or while instantiating it: mixin template foo() { int _ignoreme() { if (readln.strip == "abort") throw new AbortException; return 1; } int _alsoIgnoreMe = _ignoreme(); } void main() { mixin foo; }Awesome hack! Being a hack, it would be even nicer if it worked ouf of the box: mixin template foo(bool b) { int _impl() { writeln(b); return int.init; } int _ipml2 = _impl(); } vs mixin template foo(bool b) { writeln(b); }
Dec 21 2018
On Saturday, 22 December 2018 at 03:44:09 UTC, Timoses wrote:On Wednesday, 19 December 2018 at 15:40:50 UTC, Neia Neutuladh wrote:https://issues.dlang.org/show_bug.cgi?id=19506On Wed, 19 Dec 2018 15:12:14 +0000, bauss wrote: Or while instantiating it: mixin template foo() { int _ignoreme() { if (readln.strip == "abort") throw new AbortException; return 1; } int _alsoIgnoreMe = _ignoreme(); } void main() { mixin foo; }Awesome hack! Being a hack, it would be even nicer if it worked ouf of the box: mixin template foo(bool b) { int _impl() { writeln(b); return int.init; } int _ipml2 = _impl(); } vs mixin template foo(bool b) { writeln(b); }
Dec 22 2018
On Saturday, 22 December 2018 at 03:44:09 UTC, Timoses wrote:Awesome hack! Being a hack, it would be even nicer if it worked ouf of the box: mixin template foo(bool b) { int _impl() { writeln(b); return int.init; } int _ipml2 = _impl(); } vs mixin template foo(bool b) { writeln(b); }I think this is the closest we can come to it: mixin template Execute(alias p) { auto __execute__() { p(); return 0; } auto __unused__ = __execute__(); } mixin template MyTemplate(int a) { mixin Execute!({ import std.stdio : writeln; writeln(a); }); } void main() { mixin MyTemplate!10; }
Dec 22 2018
On Saturday, 22 December 2018 at 10:11:23 UTC, bauss wrote:On Saturday, 22 December 2018 at 03:44:09 UTC, Timoses wrote:One more line can be saved using a lambda to wrap the alias: template ExpressionStatement(alias p) { const __unused__ = {p(); return 0;}(); } Also i prefer the name `ExpressionStatement` to `Execute` because this describes exactly what the template does and define its limits at the same time. And congrats to Neia Neutuladh for this find.Awesome hack! Being a hack, it would be even nicer if it worked ouf of the box: mixin template foo(bool b) { int _impl() { writeln(b); return int.init; } int _ipml2 = _impl(); } vs mixin template foo(bool b) { writeln(b); }I think this is the closest we can come to it: mixin template Execute(alias p) { auto __execute__() { p(); return 0; } auto __unused__ = __execute__(); } mixin template MyTemplate(int a) { mixin Execute!({ import std.stdio : writeln; writeln(a); }); } void main() { mixin MyTemplate!10; }
Dec 22 2018