I'd like to lazily evaluate functions. Since calculating the return values are expensive, I have to use memoization, especially for the called subfunctions, otherwise the calculation's time complexity explodes exponentially. I need the results at compile time. (I am writing a library that provides various compile time templates based on the provided strings.) So in short, I need memoization during compile time.
std.functional.memoize
does not work CT, so it's out of question.
DMD and LDC is not clever enough to memoize pure functions, at least that's the result of my experiments for simple pure functions: The way I tested whether it caches the results:
Using simple arguments:
int sumN(int n) pure {
int result = 0;
for (int i = 0; i<=n; i++) result += i;
return result;
}
void main() {
enum sumMany = sumN(2000000);
enum sumMany2 = sumN(2000000);
writeln(sumMany, " ", sumMany2);
}
Using template arguments:
int sumN(int n)() pure {
int result = 0;
for (int i = 0; i<=n; i++) result += i;
return result;
}
void main() {
enum sumMany = sumN!2000000;
enum sumMany2 = sumN!2000000;
writeln(sumMany, " ", sumMany2);
}
Timing the compilation (calling sumN once vs twice):
time dmd -O -release -inline -boundscheck=off repeatpure.d
or
time ldc2 -O5 -release -inline -boundscheck=off repeatpure.d
The compilation time is always twice as long when I have both enums in the source code.
Is there any way to memoize CT functions?