The third type of Cicada variable is an array variable, which we define by writing the dimension inside square brackets before the element type. Multi-dimensional arrays are allowed. Examples:
numDays :: [12] int
checkerboard :: [8][8] bool
coordinates :: [] { x :: y :: double }
If we omit the dimension, as we did in defining coordinates, then a size-0 array is produced. However, it’s not quite the same as writing the [0] dimension explicitly, because empty brackets tell Cicada that the array is likely to be resized often. This array will then be given extra internal storage so that new elements can be added efficiently.
We access array elements using square brackets after the array name, just as in C. The last element can be accessed using the keyword top. To access a range of elements a through b, write [<a, b>]. To access all elements we can simply write [].
numDays[1] = 31 | assign a single element
numDays[<2, 4>] = { 31, 31, 30 } | assign 3 elements
checkerboard[1][1] = checkerboard[1][3] = true | assign 2 elements
checkerboard[3] = checkerboard[1] | assign a whole row of elements
checkerboard[top] = checkerboard[top-2] | ditto for the 6th and 8th rows
coordinates[].x = coordinates[].y | assign all 'x's
coordinates[].y = -1 | assign all 'y's (scalar-to-array copying)
Strings are effectively character arrays, and we can use array operators to access either single characters or ranges of characters. The single-element operator [n] returns a character, whereas the multi-index operator [<a, b>] returns a character array (equivalent to a string). Given two strings s1 and s2, the following commands are legal: s1 = s2[<3, 4>], s1 = s2[<4, 4>], s1 =! s2[4]; however s1 = s2[4] is illegal since Cicada does not allow char-to-string assignment. Array operators only work on string variables, not string literals, so "abc"[2] will cause an error.
Cicada has a technical restriction on the elements we can access simultaneously in multi-dimensional arrays: their memory has to be contiguous. Internally, the last index counts consecutive elements in memory; then the next-to-last index increments; etc. So the elements of some 2-dimensional array A elements are [1][1], [1][2], ..., [2][1], [2][2], ..., etc as shown in Figure 1. Here are some legal and illegal expressions involving a matrix A :: [3][4] { x :: ... }:
A[<2, 3>] | legal
A[<2, 3>][<1, 4>] | legal
A[<2, 3>][2] | will cause error
A[2][<2, 3>] | legal
A[1][2] | legal of course
A[<2, 3>][].x | legal -- x is stored separately from other members

When addressing part of an array using two or more [] or [<...>] operators, Cicada loses track of how many elements were in each dimension and thinks that it is looking at a one-dimensional list. For example, if we define:
grid :: [5][5] int
then both grid and grid[] refer to a 2-dimensional array, but grid[][] is effectively a single 1-dimensional list with 25 elements.
Last update: November 12, 2025