Request: Auto string mixin templates

nazriel spam at dzfl.pl
Tue Jul 30 05:41:00 PDT 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:
>> 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();
>> }
>
> 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!());


More information about the Digitalmars-d mailing list