Dana supports n-dimensional arrays which are either constructed or static. We'll start with constructed arrays.
These are the most common array variant, which are declared without any specific length in their declaration part:
char array[]They need to be instantiated using a construction operation before they are used. This is done with the notation:
array = new char[64]
This creates a new array of the given size, which is 64 in this case. The size can be derived from any Dana expression, such as variables or function call results.
Alternatively, a constructed array can also be instantiated by value, with the array size determined from the combination of those values:
array = new char[](y, z)
This creates a new array which has the combined size of all of the input parameters. One of the input parameters can be array itself, often used to expand an array with additional items. Character arrays in particular can be directly constructed from a string literal using the notation:
char array[] = "hello"
This notation is automatically converted by the compiler into an equivalent form to:
char array[] = new char[]("h", "e", "l", "l", "o")
The cells of an array are accessed using the typical array subscript notation:
array[0] = "m"Arrays in Dana are indexed from zero, such that array as formed above would have the content:

Any array can have its current length queried using the pseudo-attribute arrayLength:
int q = x.arrayLengthThe arrayLength operator returns the total number of cells in the array; because arrays are indexed from zero, this total cells value is one higher than the highest usable index.
Arrays of primitive type can have their cells assigned to and accessed as soon as the array has been constructed. Arrays that are formed of a data or object type are arrays of references, such that two levels of initialisation are needed when creating an array by size -- one to initialise the array itself and one to initialise each cell of the array:
x = new Cat[64]
for (int i = 0; i < 64; i++)
x[i] = new Cat()
As with data instances, constructed arrays are passed by reference, and instances are read-only at any component that did not instantiate them.
We can gain a reference to a sub-range of array cells from an existing array, using dana.sub(x, start, end). If we had an array:
char a[] = "hello"
We can then get a sub-range of this array as a direct memory reference:
char b[] = dana.sub(a, 1, 3)The array b has a length of 3, and has the contents "ell". This new array directly refers to the memory of the original array a, so any changes that we make to the values of cells in b also affect the cells of a.
We can copy cells between arrays using the syntax:
a =[] b
This copies all array cells from b over the cells of a. The operation copies as many cells as the shortest of the two array lengths and then stops.
All of the arrays in the above examples have a single dimension. We can also declare arrays with multiple dimensions, for example to represent tables (2-dimensional arrays), data cubes (3-dimensional arrays) or even higher numbers of dimensions.
In multi-dimensional arrays, the array subscripts refer to successively higher dimensions in a right-to-left order, such that the right-most subscript is equivalant to accessing cells in a one-dimensional array. Take the below example of a two-dimensional array:
int matrix[][] = new int[3][4]
This creates an array which has a row-length of 4, and which has 3 such rows:

When accessing a cell of this array, the first array subscript represents the row number, and the second array subscript represents the cell of that row. For example, the index:
int v = matrix[2][1]Accesses the highlighted cell below:

As with single-dimension arrays, multi-dimensional arrays can be constructed by length or by value. By length we use:
int ar[][] = new int[8][10]
When constructing a multi-dimensional array by value, the arrays passed in can either match the dimensionality of the target array, or can be one dimension less, for example:
int ar[][] = new int[][](new int[](1, 2, 3), new int[](4, 5, 6))
The above yields an array with two rows, each of which have three cells; the first row is (1, 2, 3) and the second row is (4, 5, 6).
Multi-dimensional arrays in Dana are allocated as a single contiguous memory block: it is not therefore necessary to separately instantiate each 'row' of a two-dimensional array. It is also not possible to, for example, assign-by-reference a one-dimensional array to be a row of a two-dimensional array (instead you must copy the values), and multi-dimensional arrays must have the same number of cells in each row of each dimension; in the above example, each row must have 3 cells.
If you include values in the array subscripts of your array variable declaration, the array has a static (fixed) size. For example, the declaration:
int values[8]Is an array with exactly 8 cells. These kinds of arrays can only be of primitive type, and do not need to be instantiated in order to be used.
Static arrays are passed by value, not by reference, such that assignments result in their content being copied into another variable.