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).