www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - One case of array assignments

reply "bearophile" <bearophileHUGS lycos.com> writes:
A small question relative to this issue (see it for more info):

http://d.puremagic.com/issues/show_bug.cgi?id=4565

Today this syntax compiles:

void main() {
     int[1][3] a2;
     a2[0][] = 1;
     a2[1][] = 2;
     a2[2][] = 3;
}



This used to compile fine, but today it gives warnings (and this 
is good):

void main() {
     int[1][3] a3;
     a3[0] = 1;
     a3[1] = 2;
     a3[2] = 3;
}


test.d(3): Warning: explicit element-wise assignment 
(a3[cast(uint)0])[] = 1 is better than a3[cast(uint)0] = 1
test.d(4): Warning: explicit element-wise assignment 
(a3[cast(uint)1])[] = 2 is better than a3[cast(uint)1] = 2
test.d(5): Warning: explicit element-wise assignment 
(a3[cast(uint)2])[] = 3 is better than a3[cast(uint)2] = 3


Those warnings come from this ER, that asks the [] to be always 
present when you perform an array operation or slice assignment 
(that is a basic array op):

http://d.puremagic.com/issues/show_bug.cgi?id=7444


Currently both of the following forms are accepted:

void main() {
     int[3] a0 = [1, 2, 3];
     int[1][3] a1 = [[1], [2], [3]];
     int[1][3] a2 = [1, 2, 3]; // Second syntax.
}


I don't like the confusion of items with single-item arrays, in 
that second syntax. (Generally in a language muddling the 
semantics or syntax leads to troubles later.)


Also visible here (this compiles):

void main() {
     char[3] a0 = ['a', 'b', 'c'];
     char[3] a1 = "abc";
     char[1][3] a2 = [['a'], ['b'], ['c']];
     char[1][3] a3 = ['a', 'b', 'c']; // Second syntax.
     char[1][3] a4 = "abc"; // Second syntax.
}


In issue 4565 I am suggesting to disallow the second syntax 
because if we are going to deprecate the assignment of array 
slices without using [], then maybe the idea of allowing both of 
those syntaxes is not good.

What do you think? Should be disallow it, or should we close 
issue 4565?

Thank you,
bye,
bearophile
Mar 11 2013
next sibling parent reply Marco Leise <Marco.Leise gmx.de> writes:
As long as this still works, as pointed out by Kenji:

  int[3] sa = 1;  // sa is initialized to [1, 1, 1]

I'm fine with disallowing:

  int[1][3] a2 = [1, 2, 3];

But that's probably only because you didn't say:

  int[100][3] a2 = [1, 2, 3];

:D

We should keep _some_ syntax for statically initializing an array
from a single element. It's a far too common task.
Mar 12 2013
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 03/13/2013 09:23 PM, John Colvin wrote:
 On Wednesday, 13 March 2013 at 20:10:14 UTC, bearophile wrote:
 int[10][3] = [1, 2, 3];

Currently that second line of code doesn't work. Bye, bearophile

It would be really nice if it did.

Then what's the meaning of int[3][3] x = [1,2,3]; Is it int[3][3] x = [[1,2,3],[1,2,3],[1,2,3]]; or int[3][3] x = [[1,1,1],[2,2,2],[3,3,3]];
Mar 13 2013
next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 03/13/2013 09:59 PM, John Colvin wrote:
 On Wednesday, 13 March 2013 at 20:46:35 UTC, Timon Gehr wrote:
 On 03/13/2013 09:23 PM, John Colvin wrote:
 On Wednesday, 13 March 2013 at 20:10:14 UTC, bearophile wrote:
 int[10][3] = [1, 2, 3];

Currently that second line of code doesn't work. Bye, bearophile

It would be really nice if it did.

Then what's the meaning of int[3][3] x = [1,2,3]; Is it int[3][3] x = [[1,2,3],[1,2,3],[1,2,3]]; or int[3][3] x = [[1,1,1],[2,2,2],[3,3,3]];

the former, clearly. It directly follows from int[3] a = 1; Every element of the array is initialised to the value given. x is an array of arrays and hence each "element-array" is initialised to the array on the right hand side.

That's clearly a valid way of reasoning, however, it is not the only one. int[3] a = 1; int[3] b = 2; int[3] c = 3; int[3][3] x = [a,b,c];
Mar 13 2013
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 03/13/2013 10:19 PM, John Colvin wrote:
 On Wednesday, 13 March 2013 at 21:08:30 UTC, Timon Gehr wrote:
 ...

 That's clearly a valid way of reasoning, however, it is not the only one.

 int[3] a = 1;
 int[3] b = 2;
 int[3] c = 3;

 int[3][3] x = [a,b,c];

this would also be valid, as you have fully specified the elements of the array. I don't see the conflict?

This was supposed to be a justification for int[3][3] x = [1,2,3]; denoting int[3][3] x = [[1,1,1],[2,2,2],[3,3,3]]; I think any one way to define the initialization semantics is arbitrary. It is not necessary anyway, the language is versatile enough: import std.stdio : writeln; import std.algorithm, std.range; auto array(R)(R r){ // phobos' version still not ctfe-able... typeof({foreach(x;r)return x;assert(0);}())[] a; foreach(x;r) a~=x; return a; } auto erep(R)(R r, size_t n){ return r.repeat(n).array; } auto emap(alias a, R)(R r){ return r.map!a.array; } auto rows(T)(T[] x,size_t n){ return x.erep(3); } auto cols(T)(T[] x,size_t n){ return x.emap!(a=>a.erep(3)); } int[3][3] x = [1,2,3].rows(3); int[3][3] y = [1,2,3].cols(3); void main(){ assert(x[]==[[1, 2, 3], [1, 2, 3], [1, 2, 3]]); assert(y[]==[[1, 1, 1], [2, 2, 2], [3, 3, 3]]); } (using one of bearophiles turned-down enhancement requests: int[$][$] x = [1,2,3].rows(3); int[$][$] y = [1,2,3].cols(3); )
Mar 13 2013
prev sibling next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 03/13/2013 10:40 PM, John Colvin wrote:
 On Wednesday, 13 March 2013 at 21:33:47 UTC, H. S. Teoh wrote:
 ...

 Why is it bad to have to explicitly list the elements for static
 initialization?


 T

I would be great if we could get rid of post-fix array declarations for good, but I'm not sure how realistic that is. It's bad to have to explicitly list them because there could be hundreds, thousands or even millions of elements.

But we have full compile-time function evaluation available, enabling initializer compression in much more involved ways.
Mar 13 2013
prev sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 03/18/2013 10:45 PM, monarch_dodra wrote:
 ...

 ubyte[4096] x = repeat( cast(ubyte)0 )[ 0 .. 4096 ].array();

 This can be used as-is inside normal code. Hwoever, array is not
 CTFE-able, so it can't work to define a struct T.init value.

Which is annoying and should be fixed.
Mar 18 2013
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 03/18/2013 11:52 PM, monarch_dodra wrote:
 On Monday, 18 March 2013 at 22:33:17 UTC, Timon Gehr wrote:
 On 03/18/2013 10:45 PM, monarch_dodra wrote:
 ...

 ubyte[4096] x = repeat( cast(ubyte)0 )[ 0 .. 4096 ].array();

 This can be used as-is inside normal code. Hwoever, array is not
 CTFE-able, so it can't work to define a struct T.init value.

Which is annoying and should be fixed.

Making array work with CTFE is a no-go, as array's job is to run-time allocate a new array.

Uh. Its job is to collect a range into an array. Implementation details are irrelevant.
 The syntax "T[N] = R.array" actually first transforms the range into a
 (dynamic) array, and then copies it into the static array. It is
 wasteful, but works. It is completely un-doable at compile time though.

You mean impossible? Of course it is possible.
 Now, if we had "staticArray(R, Sizes)(R)" transforms a range into an
 array whose size is know at compile time, then that's another story.
 It'd be more efficient at run-time, and CTFE-able

Sizes should go first.
 1) Do we want such a weird and specific function? Or is that just
 premature optimization? I mean, is there a real need?

Use 'copy'.
 2) Given CTFE's bug of "mutation implies duplication", I'm unsure
 providing such a function would be wise.

DMD bug, not CTFE bug.
Mar 18 2013
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 03/19/2013 08:18 AM, monarch_dodra wrote:
 ...

 Hum, I had meant: "staticArray(R, Sizes...)(R)" in case you wanted a
 multidim array.

 I'm not 100% sure if putting Sizes... before R mixes well.

It would have to be template staticArray(Sizes...){ auto staticArray(R)(R range){ ... } }
 1) Do we want such a weird and specific function? Or is that just
 premature optimization? I mean, is there a real need?

Use 'copy'.

Yes, but unfortunately, using 'copy' entails first declaring the variable, then copying to it, which defeats what we're trying to achieve.

staticArray is fine too.
 That said, I investigated array, and just got it to work :) And it was
 trivial, so I'll push it.

Great.
Mar 19 2013
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Marco Leise:

 But that's probably only because you didn't say:

   int[100][3] a2 = [1, 2, 3];

 :D

I don't understand.
 We should keep _some_ syntax for statically initializing an 
 array
 from a single element. It's a far too common task.

I agree. What I have suggested asks to write code like [[1], [2], [3]] instead of [1, 2, 3]. Bye, bearophile
Mar 12 2013
prev sibling next sibling parent Marco Leise <Marco.Leise gmx.de> writes:
Am Wed, 13 Mar 2013 03:45:20 +0100
schrieb "bearophile" <bearophileHUGS lycos.com>:

 Marco Leise:
 
 But that's probably only because you didn't say:

   int[100][3] a2 = [1, 2, 3];

 :D

I don't understand.

int[1][3] a2 = [1, 2, 3]; should obviously be rewritten int[1][3] a2 = [[1], [2], [3]]; but int[100][3] a2 = [1, 2, 3]; would likely have summoned a controversy about array initializers with some people finding it reasonable to do this.
 We should keep _some_ syntax for statically initializing an 
 array
 from a single element. It's a far too common task.

I agree. What I have suggested asks to write code like [[1], [2], [3]] instead of [1, 2, 3]. Bye, bearophile

That creates an inconsistency: // ok, to initialize array of ten with single literal int[10] a1 = 1; // not ok, to initialize array of ten with single literal ? int[10][3] = [1, 2, 3]; -- Marco
Mar 13 2013
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Marco Leise:

 but

 int[100][3] a2 = [1, 2, 3];

 would likely have summoned a controversy about array
 initializers with some people finding it reasonable to
 do this.

This code compiles: void main() { int[100][3] a2 = [1, 2, 3]; } And gives at run-time: object.Error: lengths don't match for array copy, 300 = 3
 That creates an inconsistency:

 // ok, to initialize array of ten with single literal
 int[10] a1 = 1;
 // not ok, to initialize array of ten with single literal ?
 int[10][3] = [1, 2, 3];

Currently that second line of code doesn't work. Bye, bearophile
Mar 13 2013
prev sibling next sibling parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Wednesday, 13 March 2013 at 20:10:14 UTC, bearophile wrote:
 int[10][3] = [1, 2, 3];

Currently that second line of code doesn't work. Bye, bearophile

It would be really nice if it did.
Mar 13 2013
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
John Colvin:

 It would be really nice if it did.

People willing to trade their language cleanliness for little handiness deserve neither and will lose both. -- Benjamin Franklin Bye, bearophile
Mar 13 2013
prev sibling next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Wed, Mar 13, 2013 at 09:54:04PM +0100, bearophile wrote:
 John Colvin:
 
It would be really nice if it did.

People willing to trade their language cleanliness for little handiness deserve neither and will lose both. -- Benjamin Franklin

Wait, really? Benjamin Franklin? I thought it was a quote I snitched from Slashdot: He who sacrifices functionality for ease of use, loses both and deserves neither. -- Slashdotter T -- My program has no bugs! Only undocumented features...
Mar 13 2013
prev sibling next sibling parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Wednesday, 13 March 2013 at 20:46:35 UTC, Timon Gehr wrote:
 On 03/13/2013 09:23 PM, John Colvin wrote:
 On Wednesday, 13 March 2013 at 20:10:14 UTC, bearophile wrote:
 int[10][3] = [1, 2, 3];

Currently that second line of code doesn't work. Bye, bearophile

It would be really nice if it did.

Then what's the meaning of int[3][3] x = [1,2,3]; Is it int[3][3] x = [[1,2,3],[1,2,3],[1,2,3]]; or int[3][3] x = [[1,1,1],[2,2,2],[3,3,3]];

the former, clearly. It directly follows from int[3] a = 1; Every element of the array is initialised to the value given. x is an array of arrays and hence each "element-array" is initialised to the array on the right hand side.
Mar 13 2013
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
H. S. Teoh:

 Wait, really? Benjamin Franklin? I thought it was a quote I 
 snitched
 from Slashdot:

I have adapted it, it's not a true quotation :-) Bye, bearophile
Mar 13 2013
prev sibling next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Wed, Mar 13, 2013 at 09:59:33PM +0100, John Colvin wrote:
 On Wednesday, 13 March 2013 at 20:46:35 UTC, Timon Gehr wrote:

Then what's the meaning of

int[3][3] x = [1,2,3];

Is it

int[3][3] x = [[1,2,3],[1,2,3],[1,2,3]];

or

int[3][3] x = [[1,1,1],[2,2,2],[3,3,3]];

the former, clearly. It directly follows from int[3] a = 1; Every element of the array is initialised to the value given. x is an array of arrays and hence each "element-array" is initialised to the array on the right hand side.

I don't like this. It adds a lot of parsing complexities just for some syntactic sugar with no clear benefits beyond being easier to type. Why not just use the existing array operations syntax? int[3] a; a[] = 1; // makes intent clear int[3][3] b; b[] = [1, 2, 3]; // fits into current syntax already T -- Today's society is one of specialization: as you grow, you learn more and more about less and less. Eventually, you know everything about nothing.
Mar 13 2013
prev sibling next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Wed, Mar 13, 2013 at 10:03:23PM +0100, bearophile wrote:
 H. S. Teoh:
 
Wait, really? Benjamin Franklin? I thought it was a quote I snitched
from Slashdot:

I have adapted it, it's not a true quotation :-)

Sure, but why Benjamin Franklin, though? (As opposed to anybody else.) Was he really the one who came up with the original expression? T -- There are three kinds of people in the world: those who can count, and those who can't.
Mar 13 2013
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
H. S. Teoh:

 Sure, but why Benjamin Franklin, though?

Because I have adapted one of the phrases attributed to him: http://en.wikiquote.org/wiki/Benjamin_Franklin Bye, bearophile
Mar 13 2013
prev sibling next sibling parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Wednesday, 13 March 2013 at 21:08:30 UTC, Timon Gehr wrote:
 On 03/13/2013 09:59 PM, John Colvin wrote:
 On Wednesday, 13 March 2013 at 20:46:35 UTC, Timon Gehr wrote:
 On 03/13/2013 09:23 PM, John Colvin wrote:
 On Wednesday, 13 March 2013 at 20:10:14 UTC, bearophile 
 wrote:
 int[10][3] = [1, 2, 3];

Currently that second line of code doesn't work. Bye, bearophile

It would be really nice if it did.

Then what's the meaning of int[3][3] x = [1,2,3]; Is it int[3][3] x = [[1,2,3],[1,2,3],[1,2,3]]; or int[3][3] x = [[1,1,1],[2,2,2],[3,3,3]];

the former, clearly. It directly follows from int[3] a = 1; Every element of the array is initialised to the value given. x is an array of arrays and hence each "element-array" is initialised to the array on the right hand side.

That's clearly a valid way of reasoning, however, it is not the only one. int[3] a = 1; int[3] b = 2; int[3] c = 3; int[3][3] x = [a,b,c];

this would also be valid, as you have fully specified the elements of the array. I don't see the conflict?
Mar 13 2013
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
One consequence of the current syntax (this is another combo), 
this is accepted:

int[1][3] a = [[1] [0], [2]];
void main() {}

Bye,
bearophile
Mar 13 2013
prev sibling next sibling parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Wednesday, 13 March 2013 at 21:07:18 UTC, H. S. Teoh wrote:
 On Wed, Mar 13, 2013 at 09:59:33PM +0100, John Colvin wrote:
 On Wednesday, 13 March 2013 at 20:46:35 UTC, Timon Gehr wrote:

Then what's the meaning of

int[3][3] x = [1,2,3];

Is it

int[3][3] x = [[1,2,3],[1,2,3],[1,2,3]];

or

int[3][3] x = [[1,1,1],[2,2,2],[3,3,3]];

the former, clearly. It directly follows from int[3] a = 1; Every element of the array is initialised to the value given. x is an array of arrays and hence each "element-array" is initialised to the array on the right hand side.

I don't like this. It adds a lot of parsing complexities just for some syntactic sugar with no clear benefits beyond being easier to type. Why not just use the existing array operations syntax? int[3] a; a[] = 1; // makes intent clear int[3][3] b; b[] = [1, 2, 3]; // fits into current syntax already T

This is supposed to be static initialisation, which is different, no?
Mar 13 2013
prev sibling next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Wed, Mar 13, 2013 at 10:20:53PM +0100, John Colvin wrote:
 On Wednesday, 13 March 2013 at 21:07:18 UTC, H. S. Teoh wrote:
On Wed, Mar 13, 2013 at 09:59:33PM +0100, John Colvin wrote:
On Wednesday, 13 March 2013 at 20:46:35 UTC, Timon Gehr wrote:

Then what's the meaning of

int[3][3] x = [1,2,3];

Is it

int[3][3] x = [[1,2,3],[1,2,3],[1,2,3]];

or

int[3][3] x = [[1,1,1],[2,2,2],[3,3,3]];

the former, clearly. It directly follows from int[3] a = 1; Every element of the array is initialised to the value given. x is an array of arrays and hence each "element-array" is initialised to the array on the right hand side.

I don't like this. It adds a lot of parsing complexities just for some syntactic sugar with no clear benefits beyond being easier to type. Why not just use the existing array operations syntax? int[3] a; a[] = 1; // makes intent clear int[3][3] b; b[] = [1, 2, 3]; // fits into current syntax already


 This is supposed to be static initialisation, which is different,
 no?

Hmm. In that case, what about a syntax adapted from the current array ops? int[3] a[] = 1; But the problem is that it's ambiguous with the current specs that interprets this as int[3][] a = 1. Why is it bad to have to explicitly list the elements for static initialization? T -- Real Programmers use "cat > a.out".
Mar 13 2013
prev sibling next sibling parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Wednesday, 13 March 2013 at 21:33:47 UTC, H. S. Teoh wrote:
 On Wed, Mar 13, 2013 at 10:20:53PM +0100, John Colvin wrote:
 On Wednesday, 13 March 2013 at 21:07:18 UTC, H. S. Teoh wrote:
On Wed, Mar 13, 2013 at 09:59:33PM +0100, John Colvin wrote:
On Wednesday, 13 March 2013 at 20:46:35 UTC, Timon Gehr 
wrote:

Then what's the meaning of

int[3][3] x = [1,2,3];

Is it

int[3][3] x = [[1,2,3],[1,2,3],[1,2,3]];

or

int[3][3] x = [[1,1,1],[2,2,2],[3,3,3]];

the former, clearly. It directly follows from int[3] a = 1; Every element of the array is initialised to the value given. x is an array of arrays and hence each "element-array" is initialised to the array on the right hand side.

I don't like this. It adds a lot of parsing complexities just for some syntactic sugar with no clear benefits beyond being easier to type. Why not just use the existing array operations syntax? int[3] a; a[] = 1; // makes intent clear int[3][3] b; b[] = [1, 2, 3]; // fits into current syntax already


 This is supposed to be static initialisation, which is 
 different,
 no?

Hmm. In that case, what about a syntax adapted from the current array ops? int[3] a[] = 1; But the problem is that it's ambiguous with the current specs that interprets this as int[3][] a = 1. Why is it bad to have to explicitly list the elements for static initialization? T

I would be great if we could get rid of post-fix array declarations for good, but I'm not sure how realistic that is. It's bad to have to explicitly list them because there could be hundreds, thousands or even millions of elements.
Mar 13 2013
prev sibling next sibling parent Marco Leise <Marco.Leise gmx.de> writes:
Am Wed, 13 Mar 2013 14:31:42 -0700
schrieb "H. S. Teoh" <hsteoh quickfur.ath.cx>:

 Why is it bad to have to explicitly list the elements for static
 initialization?

Because of: struct CompressionData { ubyte[4096] x = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]; } -- Marco
Mar 13 2013
prev sibling next sibling parent "Chris Nicholson-Sauls" <ibisbasenji gmail.com> writes:
On Thursday, 14 March 2013 at 01:34:02 UTC, Marco Leise wrote:
 Am Wed, 13 Mar 2013 14:31:42 -0700
 schrieb "H. S. Teoh" <hsteoh quickfur.ath.cx>:

 Why is it bad to have to explicitly list the elements for 
 static
 initialization?

Because of: struct CompressionData { ubyte[4096] x = [0,0,0 /* ...ad nauseum... */ ,0,0]; }

struct CompressionData { ubyte[4096] x; // note this is already [0...0] thanks // to default init... but still: this () { x[] = 0; } } --- Or even: --- import std.range; struct CompressionData { ubyte[4096] x = repeat( 0 )[ 0 .. 4096 ]; } Assuming repeat()[] is CTFE-able (didn't test).
Mar 18 2013
prev sibling next sibling parent "monarch_dodra" <monarchdodra gmail.com> writes:
On Monday, 18 March 2013 at 21:35:43 UTC, Chris Nicholson-Sauls 
wrote:
 On Thursday, 14 March 2013 at 01:34:02 UTC, Marco Leise wrote:
 Am Wed, 13 Mar 2013 14:31:42 -0700
 schrieb "H. S. Teoh" <hsteoh quickfur.ath.cx>:

 Why is it bad to have to explicitly list the elements for 
 static
 initialization?

Because of: struct CompressionData { ubyte[4096] x = [0,0,0 /* ...ad nauseum... */ ,0,0]; }

struct CompressionData { ubyte[4096] x; // note this is already [0...0] thanks // to default init... but still: this () { x[] = 0; } }

The downside here is that this requires run-time initialization.
 --- Or even: ---

 import std.range;

 struct CompressionData
 {
     ubyte[4096] x = repeat( 0 )[ 0 .. 4096 ];
 }

 Assuming repeat()[] is CTFE-able (didn't test).

Better, but that doesn't compime, because "repeat( 0 )[ 0 .. 4096 ]" is not an actual array, but a complex type. And of type int. The correct code would be: ubyte[4096] x = repeat( cast(ubyte)0 )[ 0 .. 4096 ].array(); This can be used as-is inside normal code. Hwoever, array is not CTFE-able, so it can't work to define a struct T.init value.
Mar 18 2013
prev sibling next sibling parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Monday, 18 March 2013 at 21:45:55 UTC, monarch_dodra wrote:
 The downside here is that this requires run-time initialization.

Is the normal syntax compile time actually? Incorrect dimensions for initialisation of a static array is a runtime error, so i suspect it's not.
Mar 18 2013
prev sibling next sibling parent "monarch_dodra" <monarchdodra gmail.com> writes:
On Monday, 18 March 2013 at 21:50:30 UTC, John Colvin wrote:
 On Monday, 18 March 2013 at 21:45:55 UTC, monarch_dodra wrote:
 The downside here is that this requires run-time 
 initialization.

Is the normal syntax compile time actually? Incorrect dimensions for initialisation of a static array is a runtime error, so i suspect it's not.

At worse, it is a CTFE-able syntax, because default value of all fields of a struct MUST be evaluated during compile, to evaluate T.init.
Mar 18 2013
prev sibling next sibling parent "monarch_dodra" <monarchdodra gmail.com> writes:
On Monday, 18 March 2013 at 22:33:17 UTC, Timon Gehr wrote:
 On 03/18/2013 10:45 PM, monarch_dodra wrote:
 ...

 ubyte[4096] x = repeat( cast(ubyte)0 )[ 0 .. 4096 ].array();

 This can be used as-is inside normal code. Hwoever, array is 
 not
 CTFE-able, so it can't work to define a struct T.init value.

Which is annoying and should be fixed.

Making array work with CTFE is a no-go, as array's job is to run-time allocate a new array. The syntax "T[N] = R.array" actually first transforms the range into a (dynamic) array, and then copies it into the static array. It is wasteful, but works. It is completely un-doable at compile time though. Now, if we had "staticArray(R, Sizes)(R)" transforms a range into an array whose size is know at compile time, then that's another story. It'd be more efficient at run-time, and CTFE-able 1) Do we want such a weird and specific function? Or is that just premature optimization? I mean, is there a real need? 2) Given CTFE's bug of "mutation implies duplication", I'm unsure providing such a function would be wise.
Mar 18 2013
prev sibling next sibling parent "monarch_dodra" <monarchdodra gmail.com> writes:
On Monday, 18 March 2013 at 22:59:58 UTC, Timon Gehr wrote:
 On 03/18/2013 11:52 PM, monarch_dodra wrote:
 On Monday, 18 March 2013 at 22:33:17 UTC, Timon Gehr wrote:
 On 03/18/2013 10:45 PM, monarch_dodra wrote:
 ...

 ubyte[4096] x = repeat( cast(ubyte)0 )[ 0 .. 4096 ].array();

 This can be used as-is inside normal code. Hwoever, array is 
 not
 CTFE-able, so it can't work to define a struct T.init value.

Which is annoying and should be fixed.

Making array work with CTFE is a no-go, as array's job is to run-time allocate a new array.

Uh. Its job is to collect a range into an array. Implementation details are irrelevant.

Yes, you are right. For a few seconds I though that all allocations were banned in CTFE, but it's actually hand made allocation that don't work.
 Now, if we had "staticArray(R, Sizes)(R)" transforms a range 
 into an
 array whose size is know at compile time, then that's another 
 story.
 It'd be more efficient at run-time, and CTFE-able

Sizes should go first.

Hum, I had meant: "staticArray(R, Sizes...)(R)" in case you wanted a multidim array. I'm not 100% sure if putting Sizes... before R mixes well.
 1) Do we want such a weird and specific function? Or is that 
 just
 premature optimization? I mean, is there a real need?

Use 'copy'.

Yes, but unfortunately, using 'copy' entails first declaring the variable, then copying to it, which defeats what we're trying to achieve. That said, I investigated array, and just got it to work :) And it was trivial, so I'll push it.
Mar 19 2013
prev sibling next sibling parent "monarch_dodra" <monarchdodra gmail.com> writes:
On Tuesday, 19 March 2013 at 08:19:38 UTC, Timon Gehr wrote:
 On 03/19/2013 08:18 AM, monarch_dodra wrote:

 That said, I investigated array, and just got it to work :) 
 And it was
 trivial, so I'll push it.

Great.

Done: https://github.com/D-Programming-Language/phobos/pull/1213 Now, this is legal code: //-------- unittest { //CTFE struct S { ubyte[5] a = repeat(cast(ubyte)1)[0 .. 5].array(); ubyte[5] b = iota(cast(ubyte)0, cast(ubyte)5).array(); } static assert(S.init.a[] == [1, 1, 1, 1, 1]); static assert(S.init.b[] == [0, 1, 2, 3, 4]); } //-------- Gnarly!
Mar 19 2013
prev sibling parent "Craig Dillabaugh" <cdillaba cg.scs.carleton.ca> writes:
On Monday, 18 March 2013 at 21:35:43 UTC, Chris Nicholson-Sauls
wrote:
clip
 struct CompressionData
 {
     ubyte[4096] x; // note this is already [0...0] thanks
                    // to default init... but still:

     this ()
     {
         x[] = 0;
     }
 }


 --- Or even: ---

 import std.range;

 struct CompressionData
 {
     ubyte[4096] x = repeat( 0 )[ 0 .. 4096 ];
 }

 Assuming repeat()[] is CTFE-able (didn't test).

You could also uses mixin's to build these long static arrays. I think there is a good example in Andrei's book.
Mar 19 2013