类型的类型谓词

时间:2012-10-01 15:23:55

标签: common-lisp

我希望提高收到的编译器警告的质量和数量 - Common Lisp中有一种方法可以包含类型谓词 声明的类型以及实例 - 特定于实现的答案 很好,我很想看看它是如何完成的,如果有人这样做的话。

在CCL中编译以下内容:

(defun non-list (o)
  (not (listp o)))

(deftype non-list ()
  '(satisfies non-list))

(defun example (a)
  (list a))

(declaim (ftype (function (non-list) list) example))

(defun hmm ()
  (declare (optimize (debug 3) (safety 3)))
  (let ((a '(a b c))
    (b '(d e f)))
    (declare (type list a))
    (example '(g h i))
    (example a)
    (example b)))

我会在第一次调用example时收到编译器警告 - 提供一个警告 可以针对satisfies进行检查的实例。这很好,使用调试设置我会得到一个好的运行时错误。我想知道的是,如果我能写出如下内容:

(defun non-list-typep (type)
  (not (subtypep type 'list)))

并以某种方式集成它,以便至少第二次调用 - (example a)将在编译时发出警告,因为其声明的类型list将使谓词{{1}失败}

干杯!

2 个答案:

答案 0 :(得分:7)

有点背景

有两个不同的东西:标准语言 Common Lisp 以及实现和扩展Common Lisp的各种语言。

Common Lisp作为一种语言在编译时不需要类型警告/错误。实现可以主要忽略类型声明。当编译器不忽略类型声明以及如何使用它们来静态检查类型时,该语言也没有真正描述应该做什么。

当涉及静态声明的类型时,实际Common Lisp编译器属于以下组:

  1. 主要忽略它们。例如,Symbolics Lisp Machine的编译器就属于这个组。

  2. 主要使用声明的类型进行优化。我会说CCL属于这个群体。我认为它不会对类型信息进行太多的类型推断或传播。我猜这也是编译器比SBCL更快的原因 - 它做得更少。

  3. 主要使用声明的类型进行优化,但可以进行类型推断并提供类型信息(用于优化)。例如,LispWorks属于这个群体。

  4. 使用声明的类型进行优化,进行类型推断,可以提供类型信息,并将类型声明视为编译时类型断言。 CMUCL和SBCL编译器是该组的主要成员。

  5. 因此,对于类型2的实现,如果希望编译器识别它,最好需要声明所有内容。请注意,Common Lisp提供THELOCALLY来编写声明。

    如果您希望将类型声明作为静态类型断言并让编译器检查它们,则最好使用SBCL之类的编译器。

    有关其类型声明方法的一些背景知识可以在SBCL手册中找到:Handling of TypesType Errors at Compile Time。更多背景信息:The Python Compiler for CMU Common Lisp。请注意,CMU Common Lisp(以及后来的SBCL)的编译器称为 Python - 它与编程语言 Python 无关。在 Python (1991)语言存在之前,编译器已经有了它的名字(20世纪80年代早期)。

答案 1 :(得分:1)

另一种方法是在Common Lisp上实现类型检查语言,如Qi。我想它是从一些围绕defun的智能宏开始的,以解决你所面临的问题。