Common Lisp the Language, 2nd Edition
Do not be daunted by the many options of the function make-array. All that is required to construct an array is a list of the dimensions; most of the options are for relatively esoteric applications.
make-array dimensions &key :element-type :initial-element :initial-contents :adjustable :fill-pointer :displaced-to :displaced-index-offset
This is the primitive function for making arrays. The dimensions argument should be a list of non-negative integers that are to be the dimensions of the array; the length of the list will be the dimensionality of the array. Each dimension must be smaller than array-dimension-limit, and the product of all the dimensions must be smaller than array-total-size-limit. Note that if dimensions is nil, then a zero-dimensional array is created. For convenience when making a one-dimensional array, the single dimension may be provided as an integer rather than as a list of one integer.
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. The implementation-dependent limit on array rank is reflected in array-rank-limit.
The keyword arguments for make-array are as follows:
(typep (make-array ... :element-type 'A ...) '(array A)))
is always true. See upgraded-array-element-type.
(make-array '(4 2 3) :initial-contents '(((a b c) (1 2 3)) ((d e f) (3 1 2)) ((g h i) (2 3 1)) ((j k l) (0 0 0))))
The numbers of levels in the structure must equal the rank of the array. Each leaf of the nested structure must be of the type specified by the :type option. If the :initial-contents option is omitted, the initial values of the array elements are undefined (unless the :initial-element or :displaced-to option is used). The :initial-contents option may not be used with the :initial-element or :displaced-to option.
When an array A is given as the :displaced-to argument to make-array when creating array B, then array B is said to be displaced to array A. Now the total number of elements in an array, called the total size of the array, is calculated as the product of all the dimensions (see array-total-size). It is required that the total size of A be no smaller than the sum of the total size of B plus the offset n specified by the :displaced-index-offset argument. The effect of displacing is that array B does not have any elements of its own but instead maps accesses to itself into accesses to array A. The mapping treats both arrays as if they were one-dimensional by taking the elements in row-major order, and then maps an access to element k of array B to an access to element k+n of array A.
If make-array is called with each of the :adjustable, :fill-pointer, and :displaced-to arguments either unspecified or nil, then the resulting array is guaranteed to be a simple array (see section 2.5).
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, then whether the resulting array is simple is unspecified.
Here are some examples of the use of make-array:
;;; Create a one-dimensional array of five elements. (make-array 5) ;;; Create a two-dimensional array, 3 by 4, with four-bit elements. (make-array '(3 4) :element-type '(mod 16)) ;;; Create an array of single-floats. (make-array 5 :element-type 'single-float)) ;;; Making a shared array. (setq a (make-array '(4 3))) (setq b (make-array 8 :displaced-to a :displaced-index-offset 2)) ;;; Now it is the case that: (aref b 0) == (aref a 0 2) (aref b 1) == (aref a 1 0) (aref b 2) == (aref a 1 1) (aref b 3) == (aref a 1 2) (aref b 4) == (aref a 2 0) (aref b 5) == (aref a 2 1) (aref b 6) == (aref a 2 2) (aref b 7) == (aref a 3 0)
The last example depends on the fact that arrays are, in effect, stored in row-major order for purposes of sharing. Put another way, the indices for the elements of an array are ordered lexicographically.
The value of array-rank-limit is a positive integer that is the upper exclusive bound on the rank of an array. This bound depends on the implementation but will not be smaller than 8; therefore every Common Lisp implementation supports arrays whose rank is between 0 and 7 (inclusive). (Implementors are encouraged to make this limit as large as practicable without sacrificing performance.)
The value of array-dimension-limit is a positive integer that is the upper exclusive bound on each individual dimension of an array. This bound depends on the implementation but will not be smaller than 1024. (Implementors are encouraged to make this limit as large as practicable without sacrificing performance.)
X3J13 voted in January 1989 (FIXNUM-NON-PORTABLE) to specify that the value of array-dimension-limit must be of type fixnum. This in turn implies that all valid array indices will be fixnums.
The value of array-total-size-limit is a positive integer that is the upper exclusive bound on the total number of elements in an array. This bound depends on the implementation but will not be smaller than 1024. (Implementors are encouraged to make this limit as large as practicable without sacrificing performance.)
The actual limit on array size imposed by the implementation may vary according to the :element-type of the array; in this case the value of array-total-size-limit will be the smallest of these individual limits.
vector &rest objects
The function vector is a convenient means for creating a simple general vector with specified initial contents. It is analogous to the function list.
(vector ... ) == (make-array (list n) :element-type t :initial-contents (list ... ))