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