Opened 13 years ago

Last modified 13 years ago

#409 assigned enhancement

Handling of invalid type specifiers

Reported by: gb Owned by: gb
Priority: normal Milestone:
Component: Runtime (threads, GC) Version:
Keywords: Cc:


Certain things are clearly invalid in contexts where type specifiers are expected.

Only class objects, symbols, or lists whose CARs are symbols are potentially type specifiers. CCL currently signals a SIMPLE-ERROR whenever it encounters an attempt to use some other type of object as a type specifier; this error may be signaled at compile/macroexpand-time or at runtime.

Class objects are always valid type specifiers, as are symbols that name built-in types and conses whose CARs name builtin types (assuming that the CDRs of those lists contain an appropriate number of forms:


is valid,


is clearly not a valid type specifier (and never can be.)

Some symbols can only be used as operators in compound type specifiers; this is only true of builtin types. (We don't enforce this, and treat AND and (AND) as being equivalent.) For some type X defined via DEFTYPE, X and (X) are equivalent (and both are valid if either is. (We may define some builtin types via DEFTYPE.)

Some symbols name builtin types that can be used as atomic type specifiers or as operators in compound type specifiers. (CONS and STRING are examples of such symbols.)

Some symbols can only be meaningfully used as atomic type specifiers. This is true of any builtin type that doesn't explicitly allow compound use and of symbols that would be interpreted as class names. (SEQUENCE SYMBOL) is clearly never a valid type specifier. If X is not a builtin type, then whether or not (X ...) is valid may depend on whether or not X is a proper class name or a user-defined type name, and this can change over time (though the compiler's allowed to assume that class names and superclass relationships that exist at compile-time will exist at runtime.)

The type system generally allows for the possibility that a type-specifier can be referenced (at compile/macroexpand time, certainly) before it's defined. In many cases (type predicates on slots in standard objects, MAKE-ARRAY, ...) an unknown type specifier is treated as if it specified the universal type T at runtime. I don't know to what extent existing code may rely on this behavior. (It wouldn't be totally unreasonable to issue a deferred warning for forward-referenced types and to try to resolve those warnings at the end of a compilation unit.)

It is probably reasonable (and less controversial) to distinguish between "unknown, possibly forward-referenced type specifiers" and "definitely invalid type specifiers". The latter class includes both things like 17 and things like (SEQUENCE FOO), and it's not clear that there's a significant difference between those cases. (The latter case "looks" more legitimate and may be more prevalent in some user code, but it's not really clear that there's a difference.)

There's pretty clearly a difference between (SEQUENCE FOO) and NOT-DEFINED-YET-BUT-MIGHT-BE-SOON, and runtime use of the former would be well-justified in signaling an error (as might compile-time use.)

Change History (1)

comment:1 Changed 13 years ago by gb

  • Status changed from new to assigned
Note: See TracTickets for help on using tickets.