DIP 1027---String Interpolation---Format Assessment

Adam D. Ruppe destructionator at gmail.com
Mon Feb 24 16:52:43 UTC 2020


On Monday, 24 February 2020 at 16:22:22 UTC, Atila Neves wrote:
> Thanks for the detailed write-up, there are a lot of good 
> things here.

We talked about this in the other thread, too.

I doubt the one template here will be a big deal. My experience 
is templates get bad when we use them in loops or recursion. One 
line of user code can easily expand a dozen separate 
instantiations.

Like in my jni thing, this one line: `DTypesToJni!(typeof(args))` 
expands to (args.length * 3) different templates (the impl is 
basically `alias it = AliasSeq!(convert!T[0], convert![T .. 
$])`). There's certainly the possibility it will be less, like 
foo(int, int) will be able to reuse that int one, but it is still 
work for the compiler to do.

Various std.typecons type things and std.algorithm builders can 
easily grow hugely - a range pipeline has templates returning 
templates based on templated input types.

But back to mine, since its intent is to be used in a 
__traits(allMembers) loop with different things each time, it can 
easily be hundreds of templates in two lines of user code.

Now, contrast that to a tuple builder literal, which has no 
internal recursion at all. It is just one instantiation. Even in 
a loop we might use in code generation:

static foreach(member; __traits(allMembers, T))
   mixin(i"void $member() {}".idup);


Well, each unique i"" only gives one template. That call to idup 
is a second one. So we are at two instantiations... no matter 
what the input is.


It is certainly possible to write code that does a bad job with 
it. But it is harder than you think. Even doing what I so often 
tell people not to do:


static foreach(member; __traits(allMembers, T))
   mixin(i"$(__traits(getMember, T, member).stringof) $member() 
{}".idup);


stuff like that with stringof... is still only two instantiations 
for any T. The string is still a literal and the types of the 
arguments are still the same.

I think you'd have to actively try to make more than a constant 
two template instantiations out of the i"" string. Natural uses 
will tend to give just one for the string itself and one for the 
function you call with it (which btw is already a cost we're 
paying - writeln's variadic template list does the same as it is! 
So it is really an increase of one template per use, constant. No 
multiplicative growth like with typical recursive templates, or 
worse as we see in the really pathological cases.)


More information about the Digitalmars-d-announce mailing list