D is quite specific what computations occur at compile time and what at runtime. It's very much up to the user in how he sets it up.
Evaluating functions at compile time has another wrinkle in D - it is path dependent:
int square(int x) {
if (x < 100)
return x * x;
printf("oops\n");
return 0;
}
const int x = square(3); // works
const int y = square(100); // fails at compile time
I.e. the path taken through the function has to be pure, not every part of the function.An early example was someone wrote a ray tracer in D that ran and generated output completely at compile time.
A more useful example is D's regex package can build the engine at compile time, thereby emitting a custom engine for the regex, instead of at runtime.
It would seem the startup cost of building a regexp engine would really only matter for, say, command-line programs (i.e., short-lived, run-once programs). For a web application the overhead would be negligible.
Again, don't get me wrong, but it just seems to be more of a "neat!" thing than a "we _need_ this for reasons X, Y, and Z."
So, what it _really_ provides is runtime performance.
int bar=foo();
This runs foo() at runtime: int bar;
void main(){
bar=foo();
}
There isn't any ambiguity about whether it is evaluated at runtime or compile time - there is no "fall back" to run time if it can't be done at compile time.