Cleanup Issue TYPE-OF-UNDERCONSTRAINED

Status
passed, Jun 89 X3J13
Forum
Cleanup
Category
CLARIFICATION/CHANGE
References
TYPE-OF (CLtL) 88-002R (Class-of) 88-005, p 43f, Condition system types
Related issues
SUBTYPEP-TOO-VAGUE, DATA-TYPE-HIERARCHY-UNDERSPECIFIED, FUNCTION-TYPE, ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS, COERCE-INCOMPLETE

Problem Description

The specification of TYPE-OF in CLtL is so weak as to leave it nearly useless, if any implementor actually took the specification seriously.In particular, there are almost no constraints on the value that TYPE-OF might return for any of the built in types. The only constraint placed is that for objects created by the constructor function of DEFSTRUCT, the result of TYPE-OF is the name of the defstruct.

This means that implementations could return T for all other objects.

Proposal (ADD-CONSTRAINTS)

Specify that the result of TYPE-OF satisfies the following:

(a) For any object for which (typep object built-in-type) is true when built-in-type is one of

INTEGER, RATIO, FLOAT, COMPLEX, NUMBER, NULL, SYMBOL, STRING, BIT-VECTOR, VECTOR, ARRAY, RANDOM-STATE, SEQUENCE,CONS, STREAM, PACKAGE, CHARACTER, FUNCTION, READTABLE, HASH-TABLE, PATHNAME, CONDITION, RESTART, RATIONAL, SHORT-FLOAT, LONG-FLOAT, SINGLE-FLOAT, DOUBLE-FLOAT

the result of TYPE-OF will be a type specifier for which (subtypep (type-of object) built-in-type) returns T T, i.e., either the build-in-type or a subtype of it (a subtype that the implementation's SUBTYPEP can recognize.)

(b) For all objects, (TYPEP object (TYPE-OF object)) will be true. (this implies that it will not be NIL, since no object is of type NIL.)

(c) will not be T, or use SATISFIES, AND, OR, NOT or VALUES.

(d) The type returned by TYPE-OF is always a subtype of the class returned by CLASS-OF, and is a subtype that the implementation's SUBTYPEP can recognize.

(e) For objects of metaclass STRUCTURE-CLASS or STANDARD-CLASS, TYPE-OF returns the proper name of the class returned by CLASS-OF if it has a proper name, and otherwise returns the class itself.

In particular, for objects created by the "constructor" function of a structure defined with DEFSTRUCT without a :TYPE option, TYPE-OF will return the structure name.

This proposal is intended to be consistent with 88-002R, and not to conflict with any of the definitions in that document.

Examples

It is legal for (TYPE-OF "abc") to return (SIMPLE-STRING 3), or just STRING. It is legal for (TYPE-OF 112312) to return SI:MEDIUM-SIZE-FIXNUM, as long as (SUBTYPEP 'SI:MEDIUM-SIZE-FIXNUM 'INTEGER).

Given:

   (defvar *foo* (make-array 5 :element-type t))
   (class-name (class-of *foo*))  =>  SIMPLE-VECTOR
  It is legal for
   (type-of *foo*)                =>  (SIMPLE-VECTOR 5)

Rationale

The original specification for "TYPE-OF" was written to allow implementation freedom, but the wording is in fact more vague than was intended.

Current Practice

Most Common Lisp implementations seem to implement the proposal, at least for the types we've tried them on.

Cost to Implementors

Even if there are implementations that do not currently implement the proposal, the required changes for them are likely to be minimal.

Cost to Users

Apparently none.

Cost of Non-Adoption

TYPE-OF would remain potentially inconsistent.

Performance Impact

Likely none.

Benefits

Bring the specification of TYPE-OF in like with its common implementation, while requiring it to be generally useful.

Aesthetics

Little effect.

Discussion

Originally, TYPE-OF was concieved as being useful for information display. CLOS specified CLASS-OF far more precisely, in that it must return exactly the class of an object. Unless TYPE-OF is removed from the language, it seems reasonable to require it to be at least as precise as CLASS-OF.

The accepted CLOS specification does not define CLASS-OF in terms of TYPE-OF, but an earlier draft did.

This proposal presumes the (passed) proposals DATA-TYPES-HIERARCHY-UNDERSPECIFIED:DISJOINT, FUNCTION-TYPE, and accomodates the Condition System (version 18) and CLOS.

If ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS does not pass, and this proposal does pass, it may be that the only way an implementation can satisfy (TYPEP array (TYPE-OF array)) would be to have (TYPE-OF array) return VECTOR or ARRAY as appropriate, i.e., with no element type qualification.

It is possible to constrain TYPE-OF further, e.g., to eliminate the possibility that it might return a non-portable implementation-specific value. For example, (TYPE-OF 112312) should not return SI:MEDIUM-SIZE-FIXNUM, but rather some thing like (SIGNED-BYTE 17) [if that's what SI:MEDIUM-SIZE-FIXNUM means.]

We would like to make this as an implementation recommendation, however, rather than as a constraint, at this point.

About part (c): the restriction on T is meaningless, since the CLASS-OF restriction dominates it. The restriction on MEMBER is OK, just to keep TYPE-OF from being the silly definition that (type-of x) = `(member ,x). I think we're running out of good reasons to leave out SATISFIES, AND, OR, NOT, and VALUES; they're probably no more useful, but we're probably overspecifying for no good reason.

Some types are left out of the list in (a), including:

BIGNUM and FIXNUM were left out because their division was implementation dependent.

KEYWORD was left out because under odd circumstances it is possible to dynamically change the 'type' (e.g., by UNINTERN).

STANDARD-CHAR and STRING-CHAR were left out for the same reasons they aren't built-in classes.

(These reasonas are not 100% compelling.)

Edit History