Mixin and function template?

Frits van Bommel fvbommel at REMwOVExCAPSs.nl
Thu Mar 1 14:37:05 PST 2007


renoX wrote:
> Frits van Bommel a écrit :
> [cut]
>> /** The input must be a format string with embedded "%d{var}"-style
>>  *  formatting commands
>>  */
>> char[] sputf(char[] string) {
>>     return "mixin(`std.string.format(` ~ Fmt!(" ~ escape(string) ~ ") 
>> ~ `)`)";
>> }
>>
>> void main(char[][] args) {
>>     char[] ret;
>>     int x = 2007;
>>         ret = mixin(sputf("%d{x}"));
>>         writefln("%s", ret);
>> }
> 
> The difference between your sputf and mine is that mine take a tuple
> sputf(A...) instead of a string, is it be possible to have a function 
> template take a tuple as an argument that is to say to have something like
> 
> char[] sputf(A...)()
> {
>      return "std.string.format("~Fmt!(A) ~ ");";
> }
> 
> And still call it like you do above?
> It doesn't work when I try to do this, I don't understand why..

For one thing, the ';' shouldn't be there. And the call syntax changes 
slightly, you need to add the '!' to indicate they're template 
parameters instead of function parameters. (the function call 
parentheses can be left off due to property syntax)
Then you get this:
---
import std.stdio;
import std.string;

/** dummy Fmt!() for testing. This example assumes it accepts a
  *  tuple and returns format() parameters in string form.
  */
template Fmt(A...) {
	const char[] Fmt = `"%d", x`;
}

char[] sputf(A...)()
{
      return "std.string.format(" ~ Fmt!(A) ~ ")";
}

void main(char[][] args) {
	char[] ret;
	int x = 2007;
	
	ret = mixin(sputf!("%d{x}"));
	
	writefln("%s", ret);
}
---
which seems to work.

>> As short as it is, it took me a while to get it that way.
>> This is playing with meta-levels. It mixes in a string containing a 
>> mixin expression. It used to be even worse though:
>> At first the sputf() function was just a wrapper around an adapted 
>> sputf!() template, but all the call() function did was return a 
>> mixed-in expression, which was then wrapped into a string that - when 
>> mixed in - assigned the second-level mixed-in result to a variable 
>> passed by name.
>> So it mixed in a string, that mixed in a template, that mixed in an 
>> expression -- a three-level mixin. (Careful: multiple meta-levels like 
>> that can get really confusing really quick :P)
> 
> Yes, I find it very easy to be confused.

The above is actually much clearer in implementation. A bit less nice in 
call syntax, but not by much.

>> Then I figured, that template mixin (sputfImpl!(), specifically the 
>> call() member) must be inlinable ;).
>>
>> After adding an escape() function around the format string, the result 
>> is what you see above: short but sweet.
>>
>> I hope you agree that
>> ---
>>     ret = mixin(sputf("%d{x}"));
>> ---
>> is a pretty good syntax :).
> 
> I agree, but it's a limited one: you cannot do mixin(sputf("%d",x))
> I wanted to syntax to be compatible with the old printf syntax..

Is the above what you were looking for?


More information about the Digitalmars-d-learn mailing list