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.)

Reply via email to