On Friday, 20 March 2015 at 14:20:16 UTC, John Colvin wrote:
On Friday, 20 March 2015 at 13:35:10 UTC, Dennis Ritchie wrote:
Use case?
No. I need to be able to make an array "factorials" is not
evaluated, if I don't.
import std.stdio;
enum N = 15;
static int[] factorials = memoizeFactorials(N); // lazy array?
:)
int[] memoizeFactorials(int n)
{
if (!__ctfe) {
// Make sure that this function is never called at run
time
assert(false);
}
int[] result = new int[n];
result[0] = 1;
foreach (i; 1 .. n) {
result[i] = result[i - 1] * i;
}
return result;
}
void main()
{
writeln(factorials[10]);
}
Why? To make a smaller executable? For faster compilation?
This can work
auto factorials()() @property
{
//if we're here, factorials are used somewhere
//generate them at compile-time.
enum int[N] resultsE = memoizeFactorials(N);
//put them in thread-local array on first access
static resultsS = resultsE;
return resultsS[];
}
void main()
{
writeln(factorials[10]);
}
or much easier and simpler, but different:
auto factorials()(int n)
{
//generate them at compile-time.
enum int[N] results = memoizeFactorials(N);
return results[n];
}
void main()
{
writeln(factorials(10));
}
However, none of this is a good idea at all. There are only 13
factorials (0 through 12) that fit in an int, so it's such a
small array that you might as well write
enum int[N] factorials = memoizeFactorials(N);
and be done.
I made a mistake about the static variable and thread-local
storage.
immutable(int)[] factorials()() @property
{
static immutable int[N] results = memoizeFactorials(N);
return results[];
}
is the correct way to do it if you have to.
Still, it's totally not worth doing for such a short array.