Common Lisp the Language, 2nd Edition
![]()
Next: Type Conversion
Function Up: Type
Specifiers Previous: Type
Specifiers That
New type specifiers can come into existence in two ways. First,
defining a new structure type with defstruct automatically
causes the name of the structure to be a new type specifier symbol.
Second, the deftype special form can be used to define new
type-specifier abbreviations.
[Macro]
deftype name
lambda-list
[[{declaration}*
| doc-string]]
{form}*
This is very similar to a defmacro form: name
is the symbol that identifies the type specifier being defined,
lambda-list is a lambda-list (and may contain
&optional and &rest markers), and the
forms constitute the body of the expander function. If we view
a type specifier list as a list containing the type specifier name and
some argument forms, the argument forms (unevaluated) are bound to the
corresponding parameters in lambda-list. Then the body forms
are evaluated as an implicit progn, and the value of the
last form is interpreted as a new type specifier for which the original
specifier was an abbreviation. The name is returned as the
value of the deftype form.
deftype differs from defmacro in that if no
initform is specified for an &optional
parameter, the default value is *, not
nil.
If the optional documentation string doc-string is present,
then it is attached to the name as a documentation string of
type type; see documentation.
Here are some examples of the use of deftype:
(deftype mod (n) `(integer 0 (,n)))
(deftype list () '(or null cons))
(deftype square-matrix (&optional type size)
"SQUARE-MATRIX includes all square two-dimensional arrays."
`(array ,type (,size ,size)))
(square-matrix short-float 7) means (array short-float (7 7))
(square-matrix bit) means (array bit (* *))
If the type name defined by deftype is used simply as a
type specifier symbol, it is interpreted as a type specifier list with
no argument forms. Thus, in the example above,
square-matrix would mean (array * (* *)), the
set of two-dimensional arrays. This would unfortunately fail to convey
the constraint that the two dimensions be the same;
(square-matrix bit) has the same problem. A better
definition is
(defun equidimensional (a)
(or (< (array-rank a) 2)
(apply #'= (array-dimensions a))))
(deftype square-matrix (&optional type size)
`(and (array ,type (,size ,size))
(satisfies equidimensional)))

X3J13 voted in March 1988 (FLET-IMPLICIT-BLOCK) to specify that the
body of the expander function defined by deftype is
implicitly enclosed in a block construct whose name is the
same as the name of the defined type. Therefore
return-from may be used to exit from the function.
X3J13 voted in March 1989 (DEFINING-MACROS-NON-TOP-LEVEL) to
clarify that, while defining forms normally appear at top level, it is
meaningful to place them in non-top-level contexts; deftype
must define the expander function within the enclosing lexical
environment, not within the global environment.

![]()
Next: Type Conversion
Function Up: Type
Specifiers Previous: Type
Specifiers That
AI.Repository@cs.cmu.edu