Nobody understands templates?

Chris wendlec at tcd.ie
Wed Mar 5 02:50:28 PST 2014


On Wednesday, 5 March 2014 at 02:28:00 UTC, Nick Sabalausky wrote:
> On 3/3/2014 5:35 PM, Chris wrote:
>>
>> Maybe I'm a bit too philosophical about this. But consider the 
>> following
>> (made up) case:
>>
>> struct MyTemp(T) {
>>     // ...
>>     T add(T a, T b) {
>>         if (a is string && b is string) {
>>               return a~b;  // or return a~"+"~b; or whatever
>>         } else if (a is integer && a is integer) {
>>               return a+b;
>>         }
>>     }
>> }
>>
>> I don't know if this can be considered a "pure" template. It 
>> is a
>> template of sorts, but the type specialization in the function 
>> add makes
>> it a watered-down template,
>
> Any useful template function already works that way. The mere + 
> operator is *not* one single operation, but a whole category of 
> opcodes which are chosen based on the operand's type. Thus, + 
> can be thought of as a built-in template that [roughly] does 
> this:
>
> T opPlus(T a, T b) {
>     if (T is integer) {
>         [asm opcode for 32-bit addition] a, b
>     } else if (T is ubyte) {
>         [asm opcode for 8-bit addition] a, b
>     } else if (T is float) {
>         [asm opcode for floating point addition] a, b
>     }
> }
>
> Specialization is what makes function templates useful. Some of 
> the specialization is explicit (static if) and some is implicit 
> (+ operator). But without specialization (explicit or 
> implicit), all instantiations would be identical. If all 
> instantiations are identical, why even have a template in the 
> first place?

Yes, this is perfectly clear to me. But the opcodes only matter 
to the compiler not to the programmer, i.e. the logical concept 
that one number (integer, float ...) is added to another remains 
the same. That's what I was saying.

The use of templates to avoid code duplication has been mentioned 
(cf. Sean Kelly's post), however real duplication is rare in 
specialized programs, because each function or method has it's 
own specialized job, else we wouldn't have them. Even if we 
suppose that we might want to cater for string, dchar, wchar 
without having to write the function three times, there might be 
slight differences in handling the three types so we have to fork 
within the template. What you are basically doing then is to pack 
three different functions (or the parts in which they differ) in 
one, at programming time (not compile time). This means you 
introduce three _different_ types of logic / handling mechanisms. 
Philosophically this is not a pure template, imo. The question is 
where does it end? Can you turn the whole program into one big 
template that handles all the different types and types of logic? 
(Exaggerating :-) The example I showed above is maybe not so far 
fetched add(int, int) and add(string, string).

The points you made above about OOP are very good and I'm 
increasingly unhappy with OOP's limitations. However, turning to 
templates I find myself stuck sometimes too, and I don't feel 
good about "compromising" a template by using too many if's for 
different types or introducing new logic that should actually go 
into a separate function / method. I'm really interested in 
different approaches like templates and entities, especially if 
they help optimizing code for processors and memory. However, I 
sometimes think that in Software development we always hit the 
same wall, whether we go from assembly to C, to OOP, to 
templates. The wall is that every real world program is highly 
unique and specialized and abstraction goes only so far.

One good use for templates, I figure, would be writing an 
interpreter for a scripting or DSL. As in:

greeting = "Hello, " + "world!";
result = 1 + 1;

greeting = add(string, string)
result = add(int, int)



More information about the Digitalmars-d-learn mailing list