[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Types in CL



    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)))