... It would be valid for an implementation to ... remember the
original array element-type or its canonical or expanded form ...
and satisfy all of the constraints of this proposal.
This observation makes the proposal much more palatable, so I won't
press the issue beyond the following two observations:
(1) The extra storage per array for remembering the original type can
be quite minimal, depending on the implementation. If arrays
already allocate a full pointer for the type, that can just as
well point at the pair (<upgraded-type> . <given-type>) shared
among all such arrays. If arrays use a special encoding of a few
bits to identify the updgraded type, then a small number of extra
bits suffices to index into a table of given types, overflowing
to the use of a full pointer. This does not necessarily
complicate the runtime array access code, but could require enough
trickiness in laying out arrays to be considered non-trivial.
(2) I find it esthetically disturbing that the existing proposal
seems to force the following to be legal in many implementations:
(setf (aref (the (array (unsigned-byte 5)) foo) 0)
127)
Any proposal to make such code illegal would seem to be
incompatible with ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS:UNIFY-UPGRADING
since then, e.g., for any implementation for which
(array (unsigned-byte 5)) upgrades to (array (unsigned-byte 8))
the following code would be illlegal or legal depending whether
baz is declared inline or not:
(defun baz (x) (setf (aref x 0) 127))
(defun peculiar ()
(let ((x (make-array 0 :element-type '(unsigned-byte 4))))
(declare (type (array (unsigned-byte 4)) x))
(baz x)
(aref x 0)))
In fact, I can't even portably assume that PECULIAR returns a
number, since in implementions which upgrade to (array t),
BAZ could be consistently redefined to install a string.
I keep wondering what the potential convert from FORTRAN or
PASCAL would think of all this.
Thanks for bearing with me.
jlm