On Thu, 06 Jan 2011 12:49:19 -0500, Max Samukha <[email protected]> wrote:

Some of us who have the knack of writing metaprograms in D know that many algorithms can be implemented with both recursive templates and CTFE. A simple example is map:

Recursive template instantiation:

template staticMap(alias pred, A...)
{
     static if (A.length)
         alias TypeTuple!(pred!(A[0]), staticMap!(A[1..$])) staticMap;
}

CTFE:

template staticMap(alias pred, A)
{
     mixin("alias TypeTuple!(" ~ _staticMap(A.length) ~ ") staticMap;");
}

private string _staticMap(size_t len)
{
     string result;
     if (len)
     {
         result ~= "pred!(A[0])";
         for(size_t i = 1, i < len; ++i)
         {
             result ~= ", pred!(A[" ~ to!string(i) ~ "])";
         }
     }
     return result;
}

It is not easy to decide which approach to implement in a library because both have drawbacks.

Can anybody give informed advice as to which one is preferable in practice? Or should a library provide both?

CTFE is generally easier to write/understand and more generic than doing the same thing in templates. However, there are some serious flaws in how DMD currently handles CT strings (and arrays in general) which can lead extremely complex CTFE code to be incorrect, very slow to compile or crash DMD outright. For example, I initially implemented a compile-time reflection to runtime-time reflection system for an improved std.variant using CTFE, but had to switch to templates/conditional compilation instead. (see https://jshare.johnshopkins.edu/rjacque2/public_html/) See bug 1382 (http://d.puremagic.com/issues/show_bug.cgi?id=1382).

Reply via email to