Welcome to This Week in D! Each week, we'll summarize what's been going on in the D community and write brief advice columns to help you get the most out of the D Programming Language.
The D Programming Language is a general purpose programming language that offers modern convenience, modeling power, and native efficiency with a familiar C-style syntax.
This Week in D has an RSS feed.
This Week in D is edited by Adam D. Ruppe. Contact me with any questions, comments, or contributions.
Release D 2.069.1 was an unplanned point release whose sole purpose is to fix a severe Windows installer bug.
If you are in the London area, check out the next London D Meetup - 18th November!
See more at the announce forum.
Function and struct/class templates in D are often written in short form, like so:
T foo(T)(T t) { return t; }
This is a short-hand way of writing the full version, which is:
template foo(T) { T foo(T t) { return t; } }
A template in D is a collection of declarations parameterized on a compile-time argument list. It is similar to an aggregate in that it can have several members (which you can reference with dot notation, by the way, the trick seen here is called the eponymous trick - a template member with the same name as the template itself is automatically referenced, but that's not what I want to talk about today), and those members can be of any type - including other templates.
Knowing this fact can be used to create complex multi-level templates. In cases where the compiler passes you an argument (such as implicit instantiations, opDispatch, opBinary, etc.) AND you want to pass an additional template argument, you can have trouble just doing one short-hand function with multiple arguments (Though in some cases, that does work). To achieve this, you can write the long-form style, putting a template inside a template:
struct foo { // The compiler invokes this with the string after the dot template opDispatch(string s) { // then your explicit arguments go here T implementation(T)() { return T.init + 10; } // this triggers the eponymous trick (you could // also have just named it opDispatch directly, but // the separate alias can also be used to add more // members or wrappings, so I am demoing it here) alias opDispatch = implementation; } } void main() { foo f; // runs with the arguments "intprop" and int int a = f.intprop!int; import std.stdio; writeln(a); }
Generally speaking, I think knowing the long form, or lower level implementation, is always useful. If a given feature doesn't work for you, being able to take it apart and put it back together again slightly differently can very often give you the flexibility you need. Since so much of D is made by combining building blocks, you rarely need to stop when you hit a wall - don't see it as an obstacle, see it as a source of building bricks!
To learn more about D and what's happening in D: