DEV Community

Jesse Phillips
Jesse Phillips

Posted on • Edited on

Templates

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.

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

handle!int();
Enter fullscreen mode Exit fullscreen mode

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

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

assert(handle!3() == 3);
Enter fullscreen mode Exit fullscreen mode

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.

auto x = octal!177;
Enter fullscreen mode Exit fullscreen mode

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

auto y = octal!178; // compile failure 
Enter fullscreen mode Exit fullscreen mode

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

auto z = octal!int("177");
Enter fullscreen mode Exit fullscreen mode

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.

string addTwo(alias a)() {
    return a.stringof ~ "+=2;";
} 

int four = 4;

mixin(addTwo!four);

assert(four == 6);
Enter fullscreen mode Exit fullscreen mode

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:

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

handle!int();
handle!string();
handle!bool();
Enter fullscreen mode Exit fullscreen mode

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

void handleInt() {
    int content;
} 
void handleString() {
    string content;
} 
void handleBool() {
    bool content;
} 
Enter fullscreen mode Exit fullscreen mode

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.

Top comments (0)