DEV Community

Jesse Phillips
Jesse Phillips

Posted on

Compile-Time Reflection

A mirror is a surface which creates a reflection where you can look back at yourself. This is the essence of reflection, code looking back on code. This is where meta programing lives.

Most languages choose for reflection to happen at runtime, D focuses this during compilation. Let's begin with the basics.

auto foo(T)(T a) {
    import std.conv : to;
    static if(is(typeof(a) == int))
        return a.to!string;
    static if(is(typeof(a) == string)) 
        return a.to!int;
} 

static assert(foo(6) == "6");
static assert(foo("7") == 7);
static assert(foo(foo(8)) == 8);
Enter fullscreen mode Exit fullscreen mode

This might be the basics, but this is a rediculous example. I'm wanting to show that one can access the type of a variable typeof(a), but then I throw in is expressions which is possibly one of the most complicated meta programing tool D has. I've also gone and made my template return two different types based on the argument. On top of all that it isn't even needed in this context is(T == int).


Let me shift gears to how meta programing is more frequently used.

import std.traits;

T makeLower(T)(T str) if(isSomeString!T) {
    import std.string;
    return str.toLower;
}
makeLower("Hello");
makeLower("Hello"w);
makeLower("Hello"d);
Enter fullscreen mode Exit fullscreen mode

If you read some of my other posts you'll know unicode is complicated. D has native types for UTF-8, UTF-16, UTF-32. Templates allow for writing algorithms which work with all (maintaining compile time type safety).

Templates can provide a constraint which generally examines the type and its behaviors to decide if the template is eligible for the overload set. In this particular case it is looking for types that are D native strings.


This is actually what Ranges are. Meta programing inspection of types to decide if they meet the required behavior. The only language support for range is to lower foreach loops to call popFront and empty.

Meta programing is a large topic with low level compiler traits and higher level library modules std.traits and std.meta. In D it is hard not to take advantage of its reflection when so much of its standard library is filled with its use.

Top comments (0)