• Aucun résultat trouvé

General Type Predicates

Dans le document 2. Data Types (Page 126-129)

Program Structure

6.2. Data Type Predicates

6.2.1. General Type Predicates

If a data type is viewed as the set of all objects belonging to the type, then thetypepfunction is a set membership test, whilesubtypepis a subset test.

Function]

typep object type

typepis a predicate that is true ifobjectis of typetype, and is false otherwise.

Note that an object can be \of" more than one type, since one type can include another. The type may be any of the type speciers mentioned in chapter 4exceptthat it may not be or contain a type specier list whose rst element is function or values. A specier of the form(satisfies fn) is handled simply by applying the functionfntoobject(seefuncall) theobject is considered to be of the specied type if the result is notnil.

X3J13 voted in January 1989h8ito changetypepto give specializedarray andcomplextype speciers the same meaning for purposes of type discrimi-nation as they have for declaration purposes. Of course, this also applies to such type speciers asvectorandsimple-array(see section 4.5). Thus

(typep foo '(array bignum))

in the rst edition asked the question, Is foo an array specialized to hold bignums? but under the new interpretation asks the question, Could the arrayfoohave resulted from givingbignumas the:element-typeargument tomake-array?

Function]

subtypep type1 type2

The arguments must be type speciers that are acceptable to typep. The two type speciers are compared this predicate is true iftype1 is denitely a (not necessarily proper) subtype oftype2. If the result isnil, however, then type1may or may not be a subtype oftype2(sometimes it is impossible to tell, especially when satisfiestype speciers are involved). A second returned value indicates the certainty of the result if it is true, then the rst value is an accurate indication of the subtype relationship. Thus there are three possible result combinations:

t t type1is denitely a subtype oftype2

nil t type1is denitely not a subtype oftype2

nil nil subtypepcould not determine the relationship

X3J13 voted in January 1989h171ito place certain requirements upon the implementation ofsubtypep, for it noted that implementations in many cases simply \give up" and return the two valuesnilandnilwhen in fact it would have been possible to determine the relationship between the given types.

The requirements are as follows, where it is understood that a type specier s involvesa type specier uif eitherscontains an occurrence ofudirectly or scontains a type specier wdened by deftypewhose expansion involvesu.

. subtypep is not permitted to return a second value ofnil unless one or both of its arguments involvessatisfies,and,or,not, ormember.

. subtypepshould signal an error when one or both of its arguments involves

valuesor the list form of thefunctiontype specier.

. subtypepmust always return the two valuestand tin the case where its arguments, after expansion of speciers dened by deftype, areequal.

In addition, X3J13 voted to clarify that in some cases the relationships be-tween types as reected by subtypepmay be implementation-specic. For example, in an implementation supporting only one type of oating-point number,(subtypep 'float 'long-float)would return tand t, since the two types would be identical.

Note that satisfiesis an exception because relationships between types involvingsatisfiesare undecidable in general, but (as X3J13 noted) and,

or, not, and member are merely very messy to deal with. In all likelihood these will not be addressed unless and until someone is willing to write a careful specication that covers all the cases for the processing of these type speciers bysubtypep. The requirements stated above were easy to state and probably suce for most cases of interest.

X3J13 voted in January 1989h8i to changesubtypep to give specialized

array and complex type speciers the same meaning for purposes of type discrimination as they have for declaration purposes. Of course, this also applies to such type speciers asvectorandsimple-array(see section 4.5).

If A and B are type speciers (other than *, which technically is not a type specier anyway), then (array A)and (array B)represent the same type in a given implementation if and only if they denote arrays of the same specialized representation in that implementation otherwise they are dis-joint. To put it another way, they represent the same type if and only if (upgraded-array-element-type'A) and (upgraded-array-element-type 'B)are the same type. Therefore

(subtypep '(array A) '(array B))

is true if and only if(upgraded-array-element-type 'A)is the same type as(upgraded-array-element-type 'B).

Thecomplextype specier is treated in a similar but subtly dierent man-ner. If A and B are two type speciers (but not *, which technically is not a type specier anyway), then(complex A)and(complex B)represent the same type in a given implementation if and only if they refer to com-plex numbers of the same specialized representation in that implementation otherwise they are disjoint. Note, however, that there is no function called

make-complexthat allows one to specify a particular element type (then to be upgraded) instead, one must describe specialized complex numbers in terms of the actual types of the parts from which they were constructed. There is no number of type (or rather, representation)floatas such there are only numbers of type single-float, numbers of typedouble-float, and so on.

Therefore we want (complex single-float)to be a subtype of(complex

float).

The rule, then, is that(complex A)and(complex B)represent the same type (and otherwise are disjoint) in a given implementation if and only if eitherthe type Ais a subtype ofB,or(upgraded-complex-part-type 'A) and (upgraded-complex-part-type'B) are the same type. In the latter case (complex A) and (complex B) in fact refer to the same specialized representation. Therefore

(subtypep '(complex A) '(complex B))

is true if and only if the results of(upgraded-complex-part-type 'A)and

(upgraded-complex-part-type 'B)are the same type.

Under this interpretation

(subtypep '(complex single-float)'(complex float))

must be true in all implementations but

(subtypep '(array single-float)'(array float))

is true only in implementations that do not have a specialized array represen-tation for single-float elements distinct from that for floatelements in general.

Dans le document 2. Data Types (Page 126-129)