digitalmars.D - Request: Auto string mixin templates
- JS (43/43) Jul 29 2013 I have a template t that returns a string that is always to be
- nazriel (21/64) Jul 30 2013 You already have mixin templates.
- JS (3/94) Jul 30 2013 First how does that remove having to type mixin every time?
- nazriel (23/124) Jul 30 2013 You can
- monarch_dodra (5/6) Jul 30 2013 That will *never* happen. Having the keyword *mixin* at call site
- JS (3/9) Jul 30 2013 Um, so? You think my d source is going to be hacked? Someone is
- Kenji Hara (5/18) Jul 30 2013 Two years ago I proposed the feature with experimental compiler change, ...
- JS (6/31) Jul 30 2013 I seriously don't see the issue ;/ By having some special
I have a template t that returns a string that is always to be used as a mixin. It is quite annoying to have to use mixin() on the template. e.g., mixin(t!()); It would be nice to be able to specify that the template is mixed in at the call site. e.g., string mixin template t() { ... } then t!(); // is equivalent to mixin(t!()); and no scope issues The post at http://forum.dlang.org/thread/wqmngajgejxreyzftrdw forum.dlang.org#post-wqmngajgejxreyzftrdw:40forum.dlang.org Has an example case where I have to call mixin(tJoin!(...)) to generate the code to join the strings. This statement can't be wrapped in way to simplify it without defeating the purpose of the optimization it gives. The problem is that when you use variables in a string mixin that are outside the template definition and try to string mixin(to hide the explicit mixin call), then those variables are outside the scope making the call fail. In the code above, tJoin takes a variadic set of arguments and forms a string that concatenates all of them(just as if you typed it by hand) but also deals with string arrays by inserting a call to a RT function that joins the array. so the output of tJoin is a code string that can be used to concatenate all the arguments passed to it... e.g., tJoin!(":", a, b, "c") ==> `a~b~"c"`; if a and b are strings. mixing in that string, e.g., mixin(tJoin!(":", a, b, "c")), will concatenate a with b with c... but only if in the scope of a and b. Hence, trying to wrap the mixin statement will change it's scope and a and b will either be unknown or wrong. Having someway to specify that the template should automatically be mixed in would help solve these sorts of problems(I've ran across it before when trying to generate code using a template and avoid the mixin statement). A few possible options are: string mixin template t() { ... } string template t() { ... } auto mixin template t() { ... } template t() { ... mixin enum t = ...; } template t() { ... mixin t = ...; } etc...
Jul 29 2013
On Monday, 29 July 2013 at 10:54:37 UTC, JS wrote:I have a template t that returns a string that is always to be used as a mixin. It is quite annoying to have to use mixin() on the template. e.g., mixin(t!()); It would be nice to be able to specify that the template is mixed in at the call site. e.g., string mixin template t() { ... } then t!(); // is equivalent to mixin(t!()); and no scope issues The post at http://forum.dlang.org/thread/wqmngajgejxreyzftrdw forum.dlang.org#post-wqmngajgejxreyzftrdw:40forum.dlang.org Has an example case where I have to call mixin(tJoin!(...)) to generate the code to join the strings. This statement can't be wrapped in way to simplify it without defeating the purpose of the optimization it gives. The problem is that when you use variables in a string mixin that are outside the template definition and try to string mixin(to hide the explicit mixin call), then those variables are outside the scope making the call fail. In the code above, tJoin takes a variadic set of arguments and forms a string that concatenates all of them(just as if you typed it by hand) but also deals with string arrays by inserting a call to a RT function that joins the array. so the output of tJoin is a code string that can be used to concatenate all the arguments passed to it... e.g., tJoin!(":", a, b, "c") ==> `a~b~"c"`; if a and b are strings. mixing in that string, e.g., mixin(tJoin!(":", a, b, "c")), will concatenate a with b with c... but only if in the scope of a and b. Hence, trying to wrap the mixin statement will change it's scope and a and b will either be unknown or wrong. Having someway to specify that the template should automatically be mixed in would help solve these sorts of problems(I've ran across it before when trying to generate code using a template and avoid the mixin statement). A few possible options are: string mixin template t() { ... } string template t() { ... } auto mixin template t() { ... } template t() { ... mixin enum t = ...; } template t() { ... mixin t = ...; } etc...You already have mixin templates. Eg: http://dpaste.dzfl.pl/e4b2e17a import core.stdc.stdio; mixin template Test() { class Meh { this() { printf("In Meh"); } } } void main() { mixin Test; Meh m = new Meh(); }
Jul 30 2013
On Tuesday, 30 July 2013 at 12:19:06 UTC, nazriel wrote:On Monday, 29 July 2013 at 10:54:37 UTC, JS wrote:First how does that remove having to type mixin every time? Second, Mixins are not the same as string mixins.I have a template t that returns a string that is always to be used as a mixin. It is quite annoying to have to use mixin() on the template. e.g., mixin(t!()); It would be nice to be able to specify that the template is mixed in at the call site. e.g., string mixin template t() { ... } then t!(); // is equivalent to mixin(t!()); and no scope issues The post at http://forum.dlang.org/thread/wqmngajgejxreyzftrdw forum.dlang.org#post-wqmngajgejxreyzftrdw:40forum.dlang.org Has an example case where I have to call mixin(tJoin!(...)) to generate the code to join the strings. This statement can't be wrapped in way to simplify it without defeating the purpose of the optimization it gives. The problem is that when you use variables in a string mixin that are outside the template definition and try to string mixin(to hide the explicit mixin call), then those variables are outside the scope making the call fail. In the code above, tJoin takes a variadic set of arguments and forms a string that concatenates all of them(just as if you typed it by hand) but also deals with string arrays by inserting a call to a RT function that joins the array. so the output of tJoin is a code string that can be used to concatenate all the arguments passed to it... e.g., tJoin!(":", a, b, "c") ==> `a~b~"c"`; if a and b are strings. mixing in that string, e.g., mixin(tJoin!(":", a, b, "c")), will concatenate a with b with c... but only if in the scope of a and b. Hence, trying to wrap the mixin statement will change it's scope and a and b will either be unknown or wrong. Having someway to specify that the template should automatically be mixed in would help solve these sorts of problems(I've ran across it before when trying to generate code using a template and avoid the mixin statement). A few possible options are: string mixin template t() { ... } string template t() { ... } auto mixin template t() { ... } template t() { ... mixin enum t = ...; } template t() { ... mixin t = ...; } etc...You already have mixin templates. Eg: http://dpaste.dzfl.pl/e4b2e17a import core.stdc.stdio; mixin template Test() { class Meh { this() { printf("In Meh"); } } } void main() { mixin Test; Meh m = new Meh(); }
Jul 30 2013
On Tuesday, 30 July 2013 at 12:25:47 UTC, JS wrote:On Tuesday, 30 July 2013 at 12:19:06 UTC, nazriel wrote:You can a) create wrapper mixin template _(alias T, ARGS...) { mixin(T!(ARGS)); } template Example() { enum Example = "int x = 3;"; } mixin _!Example; b) you can reuse mixin template syntax for your proposal mixin template Proposal() { enum Proposal = "int x = 3;"; } Proposal!(); But I doubt it will happen. As it is disambiguates on call site what Proposal!(); actually does/is. c) enhance template mixin to allow such constructs: mixin template Proposal() { enum Proposal = "int x = 3;"; } mixin Proposal; Still less typing that mixin(Proposal!());On Monday, 29 July 2013 at 10:54:37 UTC, JS wrote:First how does that remove having to type mixin every time? Second, Mixins are not the same as string mixins.I have a template t that returns a string that is always to be used as a mixin. It is quite annoying to have to use mixin() on the template. e.g., mixin(t!()); It would be nice to be able to specify that the template is mixed in at the call site. e.g., string mixin template t() { ... } then t!(); // is equivalent to mixin(t!()); and no scope issues The post at http://forum.dlang.org/thread/wqmngajgejxreyzftrdw forum.dlang.org#post-wqmngajgejxreyzftrdw:40forum.dlang.org Has an example case where I have to call mixin(tJoin!(...)) to generate the code to join the strings. This statement can't be wrapped in way to simplify it without defeating the purpose of the optimization it gives. The problem is that when you use variables in a string mixin that are outside the template definition and try to string mixin(to hide the explicit mixin call), then those variables are outside the scope making the call fail. In the code above, tJoin takes a variadic set of arguments and forms a string that concatenates all of them(just as if you typed it by hand) but also deals with string arrays by inserting a call to a RT function that joins the array. so the output of tJoin is a code string that can be used to concatenate all the arguments passed to it... e.g., tJoin!(":", a, b, "c") ==> `a~b~"c"`; if a and b are strings. mixing in that string, e.g., mixin(tJoin!(":", a, b, "c")), will concatenate a with b with c... but only if in the scope of a and b. Hence, trying to wrap the mixin statement will change it's scope and a and b will either be unknown or wrong. Having someway to specify that the template should automatically be mixed in would help solve these sorts of problems(I've ran across it before when trying to generate code using a template and avoid the mixin statement). A few possible options are: string mixin template t() { ... } string template t() { ... } auto mixin template t() { ... } template t() { ... mixin enum t = ...; } template t() { ... mixin t = ...; } etc...You already have mixin templates. Eg: http://dpaste.dzfl.pl/e4b2e17a import core.stdc.stdio; mixin template Test() { class Meh { this() { printf("In Meh"); } } } void main() { mixin Test; Meh m = new Meh(); }
Jul 30 2013
On Tuesday, 30 July 2013 at 12:25:47 UTC, JS wrote:First how does that remove having to type mixin every time?That will *never* happen. Having the keyword *mixin* at call site is important so the caller understand what is actually happening. Without this, you are basically injecting a macro into caller code. Good luck with the re-read.
Jul 30 2013
On Tuesday, 30 July 2013 at 13:03:47 UTC, monarch_dodra wrote:On Tuesday, 30 July 2013 at 12:25:47 UTC, JS wrote:Um, so? You think my d source is going to be hacked? Someone is going to turn all my templates into string mixins and trick me?First how does that remove having to type mixin every time?That will *never* happen. Having the keyword *mixin* at call site is important so the caller understand what is actually happening. Without this, you are basically injecting a macro into caller code. Good luck with the re-read.
Jul 30 2013
Two years ago I proposed the feature with experimental compiler change, but it was properly rejected. https://github.com/D-Programming-Language/dmd/pull/459 Kenji Hara 2013/7/30 JS <js.mdnq gmail.com>On Tuesday, 30 July 2013 at 13:03:47 UTC, monarch_dodra wrote:On Tuesday, 30 July 2013 at 12:25:47 UTC, JS wrote:Um, so? You think my d source is going to be hacked? Someone is going to turn all my templates into string mixins and trick me?First how does that remove having to type mixin every time?That will *never* happen. Having the keyword *mixin* at call site is important so the caller understand what is actually happening. Without this, you are basically injecting a macro into caller code. Good luck with the re-read.
Jul 30 2013
On Tuesday, 30 July 2013 at 14:18:20 UTC, Kenji Hara wrote:Two years ago I proposed the feature with experimental compiler change, but it was properly rejected. https://github.com/D-Programming-Language/dmd/pull/459 Kenji Hara 2013/7/30 JS <js.mdnq gmail.com>I seriously don't see the issue ;/ By having some special convention for declaring the template then any user of it should have some inclination. Progress isn't made by dumbing down to the lowest common denominator or removing all chances for failure. How bout a simple command line switch to enable the feature?On Tuesday, 30 July 2013 at 13:03:47 UTC, monarch_dodra wrote:On Tuesday, 30 July 2013 at 12:25:47 UTC, JS wrote:Um, so? You think my d source is going to be hacked? Someone is going to turn all my templates into string mixins and trick me?First how does that remove having to type mixin every time?That will *never* happen. Having the keyword *mixin* at call site is important so the caller understand what is actually happening. Without this, you are basically injecting a macro into caller code. Good luck with the re-read.
Jul 30 2013
On Tuesday, 30 July 2013 at 14:39:31 UTC, JS wrote:I seriously don't see the issue ;/ By having some special convention for declaring the template then any user of it should have some inclination. Progress isn't made by dumbing down to the lowest common denominator or removing all chances for failure. How bout a simple command line switch to enable the feature?It is major issue for code readability and clearly separating generated code from manually written one. Reading is always more important than writing when it comes to code.
Jul 30 2013
On Tuesday, 30 July 2013 at 14:49:44 UTC, Dicebot wrote:On Tuesday, 30 July 2013 at 14:39:31 UTC, JS wrote:I don't think so. If you write nice code but it is useless then there is no point in anyone reading it. If one allows proper mixin behavior and D ever gets a good ide, then it will be possible to have an intellisense like feature where string mixins are compiled and shown to the user so they can be read properly. If you block every aspect to make using such features easier then few will use them and there usage won't get easier. I think your problem is that you believe if it is not useful to you then it is not useful to anyone else.... or if it confuses you then it will confuse everyone else. It's a very arrogant attitude because everything centers around what you think. You can't expect things to be perfect right from the start... and all of programming is about making life easier for the programmer, not harder. Just because you believe such a feature will make your life more difficult doesn't make it so. The fact is, that string mixins are already hard to read... so just by removing the mixin statement won't change that. The point you are trying to make is flawed. If you are using some library and you call some template and your code blows up and you don't know why... then go read up on that function... there you'll see it is a string mixin. Then, if you get tired of all error obfuscation, go write an ide to make life easier. At some point it will be.... After all, if it were such a big deal then the feature could be removed, and it would not be hard to fix code that used it(just a simple mass search and replace). (this is only true if a special syntax was used to declare such mixins, like "string mixin template_name()". Anyways, it would be nice to actually debate the real merits of such a feature rather than feelings about it.I seriously don't see the issue ;/ By having some special convention for declaring the template then any user of it should have some inclination. Progress isn't made by dumbing down to the lowest common denominator or removing all chances for failure. How bout a simple command line switch to enable the feature?It is major issue for code readability and clearly separating generated code from manually written one. Reading is always more important than writing when it comes to code.
Jul 30 2013
On Tuesday, 30 July 2013 at 19:21:06 UTC, JS wrote:I don't think so.No one will take that from you :)If you write nice code but it is useless then there is no point in anyone reading it.Then don't write useless code. Hint: writing any piece of code longer than N involves reading it even you work alone simply because of limitations of human memory.If one allows proper mixin behavior and D ever gets a good ide, then it will be possible to have an intellisense like featurePlease no. Relying on IDE features is a major sign "bad language design".If you block every aspect to make using such features easier then few will use them and there usage won't get easier.Perfect. That is the goal. It is not newbie feature, it is complex feature, it should not be easy to slip into unnoticed.I think your problem is that you...I don't have a problem. You, however, have a problem convincing people who's opinion does matter. Hint: I am not part of that group. I am simply trying to explain in details one possible point of view why this proposal is bad. Can happily retire if you don't need it.The fact is, that string mixins are already hard to read... so just by removing the mixin statement won't change that. The point you are trying to make is flawed.That is irrelevant to actual design of string mixins. There are only very few tools to inject symbols into enclosing scope. Keeping them as explicit is possible is important for code hygiene.Anyways, it would be nice to actually debate the real merits of such a feature rather than feelings about it.Exactly. Merit: saves few symbols. Flaw: someone needs to spend time to implement it. That alone is enough to say "No".
Jul 30 2013