Date: Sun, 27 Dec 87 13:15:46 PST
From: Jon L White <edsel!jonl@labrea.stanford.edu>
re:
Actually, there is a bug in your original message, in the TYPEP call.
The predicate
(TYPEP A 'T1)
expands to
(TYPEP A '(ARRAY T2 1))
which is equivalent to
(AND (ARRAYP A)
(EQ (ARRAY-ELEMENT-TYPE A) 'T2)
(= (ARRAY-RANK A) 1)
(= (ARRAY-DIMENSION A 0) 1))
This isn't right, and is probably a good example of the single most common
error when trying to figure out what the array types mean. Since a CL
implementation of arrays is permitted to "upgrade" the :element-type
argument into something actually supported, and since there is no
requirement to preserve the original :element-type argument, then the
line above
(EQ (ARRAY-ELEMENT-TYPE A) 'T2)
should be
(SUBTYPEP 'T2 (ARRAY-ELEMENT-TYPE A))
Of course, optimizations are possible for specific T2's; but in general
the element-type might have been upgraded to, for example, T.
Just to keep the record 100% straight, SUBTYPEP isn't right.
It's true that MAKE-ARRAY and DECLARE upgrade the element type,
but TYPEP does not.
CLtL p.46 says the ARRAY type specifier -for- -discrimination-
(i.e. when used with the TYPEP function) means arrays specialized
to hold precisely the mentioned element type and no other objects,
unless the mentioned element type is *, which means all arrays.
See also the second to last paragraph on p.45. This is all a bit
strange, but it's what the book says. I suspect there are reasons
for it. We've been through this a million times on the Common Lisp
mailing list, and no one, including you and me, can remember it without
looking it up in the book each time, so it must be unintuitive.
EQ isn't right either. The function you really want is EQUAL-TYPEP,
which doesn't exist in Common Lisp, since two type specifiers can
certainly be equivalent without being EQ, and in fact without being EQUAL.
An adequate definition is probably
(defun equal-typep (t1 t2)
(and (subtypep t1 t2) (subtypep t2 t1)))