Common Lisp the Language, 2nd Edition
An array is an object with components arranged according to a Cartesian coordinate system. In general, these components may be any Lisp data objects.
The number of dimensions of an array is called its rank (this terminology is borrowed from APL); the rank is a non-negative integer. Likewise, each dimension is itself a non-negative integer. The total number of elements in the array is the product of all the dimensions.
An implementation of Common Lisp may impose a limit on the rank of an array, but this limit may not be smaller than 7. Therefore, any Common Lisp program may assume the use of arrays of rank 7 or less. (A program may determine the actual limit on array ranks for a given implementation by examining the constant array-rank-limit.)
It is permissible for a dimension to be zero. In this case, the array has no elements, and any attempt to access an element is in error. However, other properties of the array, such as the dimensions themselves, may be used. If the rank is zero, then there are no dimensions, and the product of the dimensions is then by definition 1. A zero-rank array therefore has a single element.
An array element is specified by a sequence of indices. The length of the sequence must equal the rank of the array. Each index must be a non-negative integer strictly less than the corresponding array dimension. Array indexing is therefore zero-origin, not one-origin as in (the default case of) Fortran.
As an example, suppose that the variable foo names a 3-by-5 array. Then the first index may be 0, 1, or 2, and the second index may be 0, 1, 2, 3, or 4. One may refer to array elements using the function aref; for example, (aref foo 2 1) refers to element (2, 1) of the array. Note that aref takes a variable number of arguments: an array, and as many indices as the array has dimensions. A zero-rank array has no dimensions, and therefore aref would take such an array and no indices, and return the sole element of the array.
In general, arrays can be multidimensional, can share their contents with other array objects, and can have their size altered dynamically (either enlarging or shrinking) after creation. A one-dimensional array may also have a fill pointer.
Multidimensional arrays store their components in row-major order; that is, internally a multidimensional array is stored as a one-dimensional array, with the multidimensional index sets ordered lexicographically, last index varying fastest. This is important in two situations: (1) when arrays with different dimensions share their contents, and (2) when accessing very large arrays in a virtual-memory implementation. (The first situation is a matter of semantics; the second, a matter of efficiency.)
An array that is not displaced to another array, has no fill pointer, and is not to have its size adjusted dynamically after creation is called a simple array. The user may provide declarations that certain arrays will be simple. Some implementations can handle simple arrays in an especially efficient manner; for example, simple arrays may have a more compact representation than non-simple arrays.
X3J13 voted in June 1989
(ADJUST-ARRAY-NOT-ADJUSTABLE)
to clarify that if one or more of the :adjustable, :fill-pointer,
and :displaced-to arguments is true when make-array
is called, then whether the resulting
array is simple is unspecified; but if all three arguments are false,
then the resulting array is guaranteed to be simple.