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.

Reply via email to