一个类型标识符是一个类型的名称。最简单的类型标识符是像是 integer 的符号。这些符号形成了 Common Lisp 里的类型层级。在层级的最顶端是类型 t ── 所有的对象皆为类型 t 。而类型层级不是一棵树。从 nil 至顶端有两条路,举例来说:一条从 atom ,另一条从 listsequence

    一个类型实际上只是一个对象集合。这意味着有多少类型就有多少个对象的集合:一个无穷大的数目。我们可以用原子的类型标识符 (atomic type specifiers)来表示某些集合:比如 integer 表示所有整数集合。但我们也可以建构一个复合类型标识符 (compound type specifiers)来参照到任何对象的集合。

    举例来说,如果 ab 是两个类型标识符,则 表示分别由 ab 类型所表示的联集 (union)。也就是说,一个类型 (or a b) 的对象是类型 a 或 类型 b

    如果 circular? 是一个对于 cdr 为环状的列表返回真的函数,则你可以使用适当的序列集合来表示:

    1. (integer 1 100)

    这样的类型标识符用来表示一个有限的类型 (finite type)。

    在一个复合类型标识符里,你可以通过在一个参数的位置使用 * 来留下某些未指定的信息。所以

    1. (simple-array fixnum (* *))

    描述了指定给 fixnum 使用的二维简单数组 (simple array)集合,而

    描述了指定给 finxnum 使用的简单数组集合 (前者的超类型 「supertype」)。尾随的星号可以省略,所以上个例子可以写为:

      如果有某些复合类型标识符你想重复使用,你可以使用 deftype 定义一个缩写。这个宏与 defmacro 相似,但会展开成一个类型标识符,而不是一个表达式。通过表达

      1. (deftype proseq ()
      2. '(or vector (and list (not (satisfies circular?)))))

      我们定义了 proseq 作为一个新的原子类型标识符:

      如果你定义一个接受参数的类型标识符,参数会被视为 Lisp 形式(即没有被求值),与 defmacro 一样。所以

      1. `(and integer (satisfies (lambda (x)
      2. (zerop (mod x ,n))))))

      (译注: 注意上面代码是使用反引号 ` )

      1. T

      类型标识符会被直译 (interpreted),因此很慢,所以通常你最好定义一个函数来处理这类的测试。