On Mon, 25 May 2009 14:14:17 -0400, bearophile <bearophileh...@lycos.com> wrote:
>Walter Bright: >> The problem is that enough recursion will blow up the stack in the >> compiler. I set a limit below that. But, naturally, for any limit I set >> someone will try to exceed it. > >I accept that some limits exist. For many situations a template nesting of >1000 is plenty. My problems were: >1) The limit of D1 seems different of the limit of D2, so a program I have >written for D1 doesn't work with D2. >2) Of course I have first tried to write it with CTFE, but I have failed. >First I have tried the simple solution: > >int[] genSquares(int n) { > int[] result; > for (int i = 0; i < n; i++) { > int k = i; > int m; > while (k) { > int digit = k % 10; > k /= 10; > m += digit * digit; > } > result ~= m; > } > return result; >} > >Then seeing it fail (I cast it into a fixed sized array at compile time), I >have tried creating a fixed sized array, but functions can't return them yet. >So I have tried to wrap the static array with a struct, but Don has shown this >doesn't currently work yet: > >struct S(int N) { int[N] a; } > >S!(N) genSquares(int N)() { > S!(N) s; > for (int i = 0; i < N; i++) { > int n = i; > int m = 0; > while (n) { > int digit = n % 10; > n /= 10; > m += digit * digit; > } > s.a[i] = m; > } > > return s; >} >void main() { > const int CHUNK = 1000; > static const auto squares = genSquares!(CHUNK)().a; >} > >So I have created the mixed template/ctfe version I have shown in my original >post. >So far I have written tons of (sometimes quite complex) templates in D :-) > >Max Samukha then has gently offered me a working solution, but it's not >obvious, it uses a dynamic array, but builds it in a more functional way. > >Bye, >bearophile It looks like you can workaround the bug by taking a slice of the result to "normalize" the array. This works with both compiler versions: int[] genSquares(int n) { int[] result; for (int i = 0; i < n; i++) { int k = i; int m; while (k) { int digit = k % 10; k /= 10; m += digit * digit; } result ~= m; } return result[0..n]; } void main() { const int CHUNK = 1000; static const auto squares = cast(int[CHUNK])genSquares(CHUNK); } But I'd rather use a dynamic array instead until Don fixes the bug :)