On Tuesday, 30 July 2013 at 12:25:47 UTC, JS wrote:
On Tuesday, 30 July 2013 at 12:19:06 UTC, nazriel wrote:
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/[email protected]#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();
}
First how does that remove having to type mixin every time?
Second, Mixins are not the same as string mixins.
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!());