On Tuesday, 23 July 2013 at 19:59:46 UTC, H. S. Teoh wrote:
On Tue, Jul 23, 2013 at 12:42:18PM -0700, H. S. Teoh wrote:
[...]
With the help of the new tupleReduce, you can do all sorts of
compile-time optimizations.
[...]
Here's an example of how to implement compile-time optimization
of
join() with the help of tupleReduce:
// Just for the sake of example, the following function uses
","
// to join the strings in the arguments.
string join(string[] args...) {
string result;
string delim;
foreach (arg; args) {
result ~= delim ~ arg;
delim = ","; // just for example
}
return result;
}
// This is the wrapper that uses tupleReduce (see my previous
// post) to reduce the arguments at compile-time. For
// illustration purposes, I omitted the "," from the reduction
// function, so that you can tell from the output what has been
// reduced at compile-time, and what is reduced at runtime.
template optimizedJoin(args...)
{
string optimizedJoin() {
return join(tupleReduce!((string x, string y) => x~y,
args));
}
}
void main() {
writeln(optimizedJoin!(x, "a", "bc", y, "de", "f"));
}
The output is:
runtime1,abc,runtime2,def
As you can see, "a" and "bc" have been concatenated at
compile-time, and
so have "de" and "f". Since x and y can't be read at
compile-time, they
remain as variable arguments. The optimizedJoin template then
collects
the elements of the reduced tuple and hands it off to join() to
do the
rest of the work at runtime.
Notice that join() uses "delim ~ arg" to do the concatenation at
runtime; we could ostensibly replace this with the same
function literal
we pass to tupleReduce in optimizedJoin(). Then you'll have a
full
implementation of join() that performs compile-time
optimization of its
parameters.
I rest my case. :-)
T
I must study your powerful ctfe-fu master! Great fu you have!
This is great that D can do this and from just a quick glance it
looks like you solve the problem.
Your code doesn't exactly do what I wanted but probably because I
wasn't clear... I think it is modifiable and solves the problem I
was having(again, assuming your code is correct).
Note though that something like
string x = "asd"
join(x,...); // x is compile time known and should be joined at
compile time. Not sure if D is smart enough to get this one?
When I get some time later I'll check your code out, what I want
to do is get something like
string x = join(a, b, "a", "b"); to produce the same code as
string x = a~b~"ab";
(no looping using for each except for string arrays)
Thanks!