Problem Description:
Types are not first class objects in Lisp. They can only be referred to indirectly with type specifiers, which are environment dependent. There is no way to determine if a given object is a valid type specifier in any environment.
Proposal:
Add a type type
defined below. Add it to the pairwise disjoint types listed in 4.2.2 "Type Relationships". Define that types are externalizable, and that types are similar if they refer to similar sets; more specifically, that two types corresponding to classes are similar if those classes are similar, that two satisfies types are similar if they have the same function name, bla bla bla it should all be pretty intuitive.
Add the function specifier-type
defined below.
Edit the description of operators that input type specifiers (including but not limited to typep
, subtypep
, upgraded-array-element-type
, the
) so that they take types instead. Define the concept of a "type designator", which is either a type (designating itself) or a type specifier and accompanying environment. So, for example, (typep obj ty env)
would be equivalent to (typep obj (specifier-type ty env))
.
Edit the description of operators that output type specifiers (e.g. upgraded-array-element-type
) to make them output types instead.
Define that types can be used as type specifiers. This allows, for example, (or some-type some-other-type)
to be a valid type specifier, and so types can be dealt with algebraically without adding type-union
, etc.
Rationale:
Defines types as first class while maintaining compatibility.
Cost to Implementors:
Implementations that already define a reified type representation internally, e.g. for use in their compilers, could clean up and export it relatively simply.
Implementations that don't would have to do more work. The simplest strategy would probably be to define a new structure- or standard-object for type
, with a type specifier in a slot. Then specifier-type
would simply fully macroexpand its argument, and put the resulting macroexpansion in one of these type
objects.
The restrictions given do not rule out using class objects as type objects directly.
Cost to Users:
Little or none. Anybody using the specifier-type
name might be in a little trouble. Users are already forbidden from defining cl:type
as a type per CLHS 11.1.2.1.2 so there's no problem there.
Cost of Non-Adoption:
Status quo.
Benefits:
Aesthetics:
Discussion:
An inverse function type-specifier
to get a specifier for a type may be useful for display purposes. However, it's inherently odd to define in the same way a function to return a form given a value it evaluates to would be.
Function SPECIFIER-TYPE
Syntax:
specifier-type type-specifier &optional
environment => type
Arguments and Values:
type-specifier---a type specifier.
env---an environment object. The default is nil.
type---a type.
Description:
specifier-type returns the type specified by the given type specifier in env.
The returned type is independent of type names in environment. In particular, any and all type macros specified must have been fully expanded.
Exceptional Situations:
If the type-specifier is not valid, specifier-type signals an error of type error.