<div dir="ltr">On 8 July 2013 21:16, Martin Nowak <span dir="ltr"><<a href="mailto:code@dawg.eu" target="_blank">code@dawg.eu</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im">On 07/06/2013 03:34 AM, Manu wrote:<br>
</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">
Okay, so I feel like this should be possible, but I can't make it work...<br>
I want to use template deduction to deduce the argument type, but I want<br>
the function arg to be Unqual!T of the deduced type, rather than the<br>
verbatim type of the argument given.<br>
<br>
I've tried: void f(T : Unqual!U, U)(T a) {}<br>
and: void f(T)(Unqual!T a) {}<br>
<br></div><div class="im">
Ie, if called with:<br>
   const int x;<br>
   f(x);<br>
Then f() should be generated void f(int) rather than void f(const int).<br>
<br>
</div></blockquote>
I can't find the Bugzilla entry right now, but we discussed before why it is not generally possible to deduce A from a match of type B with Template!A. Basically you'd need the inverse of the Template and the type mapping would need to be bijectiv.<br>

<br>
What does work though and looks similar is to deduce A from a match of Template!B with Template!A.</blockquote><div><br></div><div style>I'm not sure I follow. Can you demonstrate?</div><div><br></div><div><br></div>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I don't want a million permutations of the template function for each<br>
combination of const/immutabe/shared/etc, which especially blows out<br>
when the function has 2 or more args.<br>
<br>
Note: T may only be a primitive type. Obviously const(int*) can never be<br>
passed to int*.<br>
</blockquote>
<br></div>
There is a linker optimization that would get rid of the duplicates.<br>
<a href="http://stackoverflow.com/questions/15168924/gcc-clang-merging-functions-with-identical-instructions-comdat-folding" target="_blank">http://stackoverflow.com/<u></u>questions/15168924/gcc-clang-<u></u>merging-functions-with-<u></u>identical-instructions-comdat-<u></u>folding</a><br>

<br>
I came up with "out-of-bound" template instantiations to avoid unneeded instantiations.<br>
What you do is to forward common template code to another template that is next to the actual template. The next to is important because it allows to merge identical instantiations.<br>
For example this idiom is useful when you pass additional arguments to your template, e.g. __FILE__ and __LINE__.<br>
<br>
void _f(T)(T a) {}<br>
void f(T)(T a) { return _f!(Unqual!T)(a); }<br>
<br>
template _f(CommonArgs) { enum _f = foo!CommonArgs; }<br>
template f(CommonArgs, MoreArgs) { static assert(bar!MoreArgs); enum f = _f!CommonArgs; }<br>
</blockquote></div><br></div><div class="gmail_extra" style>I really hate relying on linker optimisations to clean up mess like this, which simply shouldn't exist in the first place.</div><div class="gmail_extra" style>
Debugging is critically important. In my experience, most programmers spend 90% of their time debugging, and that means debug builds still need to be usable. Unoptimised code isn't THAT much slower/bigger by nature. But there's a big different between 10 times slower and 100 times slower. Likewise, there's also a big difference between twice as big, and 10 times as big. Depending on the optimiser to eliminate this sort of duplication tends your debug code towards the latter.</div>
<div class="gmail_extra" style><br></div><div class="gmail_extra" style>At my prior company, we were very proud that our debug build still ran at ~10fps (playable/testable)... most companies debug builds run closer to 1fps or less, which means you can't practically test AND debug your code. It's very hard to reveal the bug you're chasing if you can't physically test the build.</div>
<div class="gmail_extra" style>Every new person we employed was amazed, and commented on this. It was without doubt, a strategic advantage for our company. And the reason we succeeded to this end, was simply because we banned C++ (well, most of it) :/</div>
<div class="gmail_extra" style>D makes templates so convenient, one can imagine the typical situation might even be worse than typical C++. So instead, D needs to take the opportunity to offer tools to allow the programmer to express what they actually want, rather than generating copious bloat, and expecting optimisation passes to clean it up.</div>
<div class="gmail_extra" style><br></div><div class="gmail_extra" style>Forwarding to secondary functions like this is really horrible. So now my 'optimisation' (it's not an optimisation, it's just what I want to do in the first place) requires that I mutilate my code. What are the sensible naming conventions for this scheme? Does this really improve readability? What about find-in-files/go-to-definition?</div>
<div class="gmail_extra" style>I'm sure we can do better than this... actually, we must. I won't accept this. Bloat should be factored out by design. It's not something that should be ignored, and then attempted to clean up later.</div>
<div class="gmail_extra" style><br></div><div class="gmail_extra" style>So I'm back where I started :/</div><div class="gmail_extra" style>Again, from the top, I want more control over the template argument deduction.</div>
<div class="gmail_extra" style><br></div><div class="gmail_extra" style>I want this for example:</div><div class="gmail_extra" style>  void f(T)(Unqual!T arg);<br></div><div class="gmail_extra" style><br></div><div class="gmail_extra" style>
When called with:</div><div class="gmail_extra" style>  int x;</div><div class="gmail_extra" style>  const(int) cx;</div><div class="gmail_extra" style>  immutable(int) ix;</div><div class="gmail_extra" style>  shared(int) sx;</div>
<div class="gmail_extra" style><br></div><div class="gmail_extra" style>  f(x);</div><div class="gmail_extra" style>  f(cx);</div><div class="gmail_extra" style>  f(ix);</div><div class="gmail_extra" style>  f(sx);</div><div class="gmail_extra" style>
<br></div><div class="gmail_extra" style>All calls deduce the template instantiation: void f(int)(int arg);</div><div class="gmail_extra" style><br></div><div class="gmail_extra" style>I can see why my example syntax doesn't work. The 'T' in the argument list is actually the inverse of what I want, like you say.</div>
<div class="gmail_extra" style>But I'm sure there are tweaks on the expression that could possibly make sense somehow.</div><div class="gmail_extra" style>Basically, is it possible? Is there another approach that could produce the same outcome; that is, having more control over the template argument deduction, and consequently, the resulting template instantiation?</div>
<div class="gmail_extra" style><br></div><div class="gmail_extra" style>Some creative thought can surely crack this nut. I think this is a severe issue, and worth some serious attention. I'm rather surprised how few of the heavy weights have commented on this topic :(</div>
</div>