Templates
Tags: dlang, tutorial, templates, generics
Published: 2019-10-20 01:05:05


# Intro

Templates have been around for some time, C++ being the most well-known language to support them. They are turning complete, and if you have only worked with them in C++ you're likely glad Java, C#, and Go don't have them.

Templates are one strategy to writing generic code. You'll see similar concepts in the Java and C# feature known as generics. Templates harbor much more power, and D takes that power to the max.

I mentioned templates being Turing complete, I must first note this is generally avoided in D because of compile time function evaluation (CTFE). What I want to focus on is the consept. 

Templates are a compile time construct. They can be thought of as a function which takes compile time arguments (hence my note about CTFE).

# Compile Time Arguments 

What is a compile time argument?

* Types 
* Values
* Symbols

## Types

Types are the most common, and what generics tackles. In this case the template creates a symbol to the type allowing for the template. Enough talk let's look at some code.

```dlang
void handle(T)() {
    T content;
} 

handle!int();
```

This is not a helpful template, takes no arguments and returns nothing. What I'm trying to show is how T becomes a symbol representing a type. In this particular example `T` is `int`. D has chosen !() to indicate compile time parameters (the parentheses can be dropped for a single argument).

## Values 

```dlang
int handle(int val)() {
    return val;
} 

assert(handle!3() == 3);
```

By itself this ability is not very valuable, `static if`, `static assert` and other compile time inspection brings the ability to create restrictions and generate new code.

```dlang
auto x = octal!177;
```

This is how octal and hex literals are handled. This even prevents compiling invalid octal digits, though the failure message could be improved.

```dlang
auto y = octal!178; // compile failure 
```

As I noted, the power isn't in the template. This actually converts the integer to a string and then executes normal conversion routine.

```dlang 
auto z = octal!int("177");
```

This is the same executed code, but it will evaluate at runtime.

## Symbols

This is one of the most versatile compile time parameters. Without getting technical, almost all of a programming language is a symbol of some sort. This means types and values can be passed as a symbol.

When trying to think of an example of using a symbol, the main challenge was choosing something distinguishing and to really show how aliasing works. I decided some code generation was the answer. 

```dlang 
string addTwo(alias a)() {
    return a.stringof ~ "+=2;";
} 
    
int four = 4;
    
mixin(addTwo!four);
    
assert(four == 6);
```

In this example addTwo builds the string `four+=2;`. Then within the context of the context of 'four' `mixin` is used compile that string in that context.

`alias` has given access to the symbol `four` where we used the language feature `stringof` to get the string representing that symbol.

Look at that, a five line example and we not only use templates, but also compile time evaluation and code generation.

# Templates

Templates create a structure for code and uses compile time variables as place holders for different parts of the code. If we take the first example and add different instantiations:


```dlang
void handle(T)() {
    T content;
} 

handle!int();
handle!string();
handle!bool();
```

The compiler does the work of generating (the names are made-up and the points don't matter). 


```dlang
void handleInt() {
    int content;
} 
void handleString() {
    string content;
} 
void handleBool() {
    bool content;
} 
```

D expands on this concept and mixes it with the reasons languages have functions.

# Comment 

This post actually bugs me. I was looking over available articles to read and one of them was about object oriented programming in C#.

The issue with these type of posts is that they are a technical explanation of the tool. They rarely give a good caviots to the problems to using these tools and when to reach for them.