**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.

AI.Repository@cs.cmu.edu