ADJUST-ARRAY-NOT-ADJUSTABLEADJUST-ARRAY works only on an implementation-dependent subset of arrays.
The description of the :ADJUSTABLE option to MAKE-ARRAY on p288 says that ``the argument, if specified and not NIL, indicates that it must be possible to alter the array's size dynamically after it is created. This argument defaults to NIL.'' The description of the :ADJUSTABLE option does not say what MAKE-ARRAY will do if the argument is unsupplied or explicitly NIL.
The description of ADJUSTABLE-ARRAY-P on p293 says that it is true ``if the argument (which must be an array) is adjustable, and otherwise false.'' However, the description of MAKE-ARRAY makes it clear that this is not necessarily the same as asking if the array was created with :ADJUSTABLE T. If ADJUSTABLE-ARRAY-P returns NIL, you know that :ADJUSTABLE NIL was supplied (or no :ADJUSTABLE option was supplied), but if ADJUSTABLE-ARRAY-P returns T, then there is no information about whether :ADJUSTABLE was used.
The description of ADJUST-ARRAY on pp297-298 says that it is ``not permitted to call ADJUST-ARRAY on an array that was not created with the :ADJUSTABLE option.'' This is inconsistent with ADJUSTABLE-ARRAY-P.
The definition of SIMPLE-ARRAY on p.28 says ``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.'' It is left unclear whether this is an implication or an equivalence, i.e. whether there can be other simple arrays as well. CLtL p.299 appears to refer to simple strings with fill pointers, suggesting that it is an implication, but similar language is used for equivalences in other parts of CLtL.
MAKE-ARRAY is called with the :ADJUSTABLE, :FILL-POINTER, and :DISPLACED-TO arguments each either unspecified or false, the resulting array is a simple array. (This just repeats what CLtL says on page 289, it's here to aid in understanding the next point.)
2. If MAKE-ARRAY is called with one or more of the :ADJUSTABLE, :FILL-POINTER, or :DISPLACED-TO arguments true, whether the resulting array is simple is unspecified.
3. It is permitted to call ADJUST-ARRAY on any array. (Remove the restriction documented at the bottom of p.297.)
4. If ADJUST-ARRAY is applied to an array created with :ADJUSTABLE true, the array returned is EQ to its first argument. It is not specified whether ADJUST-ARRAY returns an array EQ to its first argument for any other arrays. If the array returned by ADJUST-ARRAY is not EQ to its first argument, the original array is unchanged and does not share storage with the new array.
5. The predicate ADJUSTABLE-ARRAY-P is true if and only if ADJUST-ARRAY will return a value EQ to this array when given this array as its first argument.
Clarifications and Logical Consequences:
a. There is no specified way to create an array for which ADJUSTABLE-ARRAY-P definitely returns NIL.
b. There is no specified way to create an array that is non-simple.
c. The definition of SIMPLE-ARRAY on p.28 is taken to be an implication, not an equivalence. This is either a clarification or a change depending on one's prior reading of that definition.
d. The meaning of ADJUSTABLE-ARRAY-P is changed.
e. As with such functions as DELETE and NCONC, textbooks should instruct programmers to be careful to receive the value returned by ADJUST-ARRAY, as it might not be EQ to the first argument.
f. VECTOR-PUSH-EXTEND still signals an error if given a non-adjustable array. ADJUST-ARRAY's new feature of making a copy cannot be used by VECTOR-PUSH-EXTEND, since there is no way to return the copy to the caller.
ADJUST-ARRAY only working on a subset of arrays, by changing it to work on all arrays. It remains implementation-dependent whether the array is modified in place or copied, i.e. whether the result is EQ to the argument, however many other functions in Common Lisp have similar implementation-dependent behavior. Implementation-dependent storage allocation or reuse is considered more benign than implementation-dependent applicability of an operation.
Point 3 recognizes that ADJUST-ARRAY offers features that are offered by no other function and which are useful in cases involving non-adjustable arrays (for what amounts to copying). This change would allow an expression such as:
(SETQ X (ADJUST-ARRAY X ...))
to work reliably. Those desiring the old behavior could do:
(IF (OR (NOT (ADJUSTABLE-ARRAY-P X))
(NOT (EQUAL (ARRAY-RANK X) (LENGTH NEW-DIMENSIONS))))
(ERROR "Array cannot be adjusted."))
to get the old style error checking.
Point 5 recycles the name ADJUSTABLE-ARRAY-P as a test for whether an array is adjusted in place or by copying.
Point 2 preserves the raison d'etre of simple arrays, which is to provide a portable interface to implementation-dependent specialized arrays that trade decreased functionality for faster access. A proposed alternative was to specify a way to create an array that is guaranteed not to be simple. This would have made (typep (make-array ...) 'simple-array) return the same value in all implementations, but would have required large changes to some implementations and would be of little benefit to users. Users need to know that certain arrays are simple, so they can put in declarations and get higher performance, but users have no need to be able to create arrays that are definitely non-simple (for lower performance) or definitely non-adjustable.
(defun double (a)
(adjust-array a (* (length a) 2)))
(double (make-array 30))
2. The following program is conforming. In no implementation is the type declaration violated.
(let ((a (make-array 100)))
(declare (simple-array a))
(frob a))
3. The following program is non-conforming. The consequences of this program are undefined because the type declaration is violated in some implementations.
(let ((a (make-array 100 :adjustable t)))
(declare (simple-array a))
(frob a))
ADJUST-ARRAY. Point 5 may involve a change to ADJUSTABLE-ARRAY-P or may be able to use the existing implementation of the function.
Symbolics Genera makes :ADJUSTABLE NIL arrays adjustable in most cases, and ignores adjustability in deciding whether an array is a SIMPLE-ARRAY. The arrays that are internally simple in Symbolics Genera are a different subset of arrays from the type SIMPLE-ARRAY, because simplicity in that implementation depends on the rank and total-size as well as on the fill-pointer and displacement, thus Genera does not use the type SIMPLE-ARRAY for anything.
Lucid, IIM, Ibuki, and Symbolics Cloe make :ADJUSTABLE NIL arrays non-adjustable in all cases, and make every array non-simple that CLTL does not require to be simple.
Macintosh Allegro Common Lisp v1.2 makes :ADJUSTABLE NIL arrays non-adjustable in all cases, makes all arrays of rank other than 1 non-simple (violating point 1), and makes every array non-simple that CLTL does not require to be simple.
ADJUSTABLE-ARRAY-P is easy. The change to ADJUST-ARRAY may involve some complex coding but should not be a large task. No changes are required to anything connected with SIMPLE-ARRAY.ADJUSTABLE-ARRAY-P. This is a fully upward-compatible change from the user's standpoint.ADJUST-ARRAY, as its use will not be restricted to a subset of arrays.:ADJUSTABLE NIL to signal an error would not get the desired signal. A few programs might have porting problems due to variation among implementations of whether the result of ADJUST-ARRAY is EQ to the first argument.ADJUST-ARRAY on all arrays is an aesthetic improvement.Dick Gabriel, Dave Moon, and Guy Steele support this proposal.
Some commentors would like to get rid of ADJUSTABLE-ARRAY-P, since ADJUST-ARRAY now works on all arrays. Other commentors have said that ADJUSTABLE-ARRAY-P is still needed in some applications, such as user written functions that behave like VECTOR-PUSH-EXTEND, and hence should be kept; the concept of "adjustable array" is still meaningful.
----- End Forwarded Messages -----