If type-1 is a recognizable subtype of type-2,
the first value is true.
Otherwise, the first value is false,
indicating that either
type-1 is not a subtype of type-2, or else
type-1 is a subtype of type-2
but is not a recognizable subtype.
A second value is also returned indicating the `certainty' of
the first value. If this value is true, then the first
value is an accurate indication of the subtype relationship.
(The second value is always true when the first value
is true.)
The next figure summarizes the possible combinations of values
that might result.
subtypep is permitted to return the
values false and false only when at least
one argument involves one of these type specifiers:
and,
eql,
the list form of function,
member,
not,
or,
satisfies,
or
values.
(A type specifier `involves' such a symbol if,
after being type expanded,
it contains that symbol in a position that would call for
its meaning as a type specifier to be used.)
One consequence of this is that if neither type-1 nor type-2
involves any of these type specifiers, then subtypep is obliged
to determine the relationship accurately. In particular, subtypep
returns the values true and true
if the arguments are equal and do not involve
any of these type specifiers.
subtypep never returns a second value of nil when both
type-1 and type-2 involve only
the names in Figure 4.2.3 Type Specifiers, or
names of types defined by defstruct,
define-condition,
or defclass, or
derived types that expand into only those names.
While type specifiers listed in Figure 4.2.3 Type Specifiers and
names of defclass and defstruct can in some cases be
implemented as derived types, subtypep regards them as primitive.
The relationships between types reflected by subtypep
are those specific to the particular implementation. For example, if
an implementation supports only a single type of floating-point numbers,
in that implementation (subtypep 'float 'long-float)
returns the values true and true
(since the two types are identical).
For all T1 and T2 other than *,
(array T1) and (array T2)
are two different type specifiers that always refer to the same sets of
things if and only if they refer to arrays
of exactly the same specialized representation, i.e.,
if (upgraded-array-element-type 'T1) and
(upgraded-array-element-type 'T2)
return two different type specifiers that always refer to the same sets of
objects.
This is another way of saying that
`(array type-specifier)
and
`(array ,(upgraded-array-element-type 'type-specifier))
refer to the same
set of specialized array representations.
For all T1 and T2 other than *,
(array T1)
and (array T2) is the empty set
if and only if they refer to arrays of different,
distinct specialized representations.
Therefore,
(subtypep '(array T1) '(array T2)) true
if and only if
(upgraded-array-element-type 'T1) and
(upgraded-array-element-type 'T2)
return two different type specifiers that always refer to the same sets of
objects.
For all type-specifiers T1 and T2 other than *,
(subtypep '(complex T1) '(complex T2)) true, true
if:
- 1. T1 is a subtype of T2, or
- 2. (upgraded-complex-part-type 'T1) and
(upgraded-complex-part-type 'T2)
return two different type specifiers that always refer to the
same sets of objects; in this case,
(complex T1) and
(complex T2) both refer to the
same specialized representation.
The values are false and true otherwise.
The form
(subtypep '(complex single-float) '(complex float))
must return true in all implementations, but
(subtypep '(array single-float) '(array float))
returns true only in implementations that do not have a specialized array
representation for single floats distinct from that for other floats.
(subtypep 'compiled-function 'function) true, true
(subtypep 'null 'list) true, true
(subtypep 'null 'symbol) true, true
(subtypep 'integer 'string) false, true
(subtypep '(satisfies ) nil) false, implementation-dependent
(subtypep '(integer 1 3) '(integer 1 4)) true, true
(subtypep '(integer (0) (0)) 'nil) true, true
(subtypep 'nil '(integer (0) (0))) true, true
(subtypep '(integer (0) (0)) '(member)) true, true ;or false, false
(subtypep '(member) 'nil) true, true ;or false, false
(subtypep 'nil '(member)) true, true ;or false, false
Let <aet-x> and <aet-y> be two distinct type specifiers that
do not always refer to the same sets of
objects
in a given implementation, but for which
make-array, will return an
object of the same array type.
Thus, in each case,
(subtypep (array-element-type (make-array 0 :element-type '<aet-x>))
(array-element-type (make-array 0 :element-type '<aet-y>)))
true, true
(subtypep (array-element-type (make-array 0 :element-type '<aet-y>))
(array-element-type (make-array 0 :element-type '<aet-x>)))
true, true
If (array <aet-x>)
and (array <aet-y>) are different names for
exactly the same set of objects,
these names should always refer to the same sets of
objects.
That implies that the following set of tests are also true:
(subtypep '(array <aet-x>) '(array <aet-y>)) true, true
(subtypep '(array <aet-y>) '(array <aet-x>)) true, true