On Thursday, January 06, 2011 09:49:19 Max Samukha 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?
I suppose that in theory, I would say to use templates for things that really are intended to always be used at compile time and CTFE for functions which would make sense both for compile time and runtime. But whether that's actually the best practice (particularly given the current state of dmd and CTFE), I don't know. Personally, I think what generally happens in that when I'm trying to do something which needs to be done at compile time, I use CTFE if a function already exists which will do what I want, and I use a template if it doesn't. Or if it's something that I know that I need to be used both at compile time and runtime, then I make it a function for use with CTFE. I think that in at least one case, I've created a template for use at compile time and a function for use at runtime so that I could have additional checks or different behavior at runtime (I think that I had it throw an exception at runtime, which you can't do at compile time), but that's not the norm. I don't know. I've rarely sat down and tried to decide whether something should be a template or a CTFE-able function. I think that it most cases I've either been creating a function for runtime and possible used it also at compile time, or I've needed something at compile time, so I've created a template. - Jonathan M Davis