3

我希望提高我收到的编译器警告的质量和数量——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会使谓词失败non-list-typep

干杯!

4

2 回答 2

8

A bit background:

There are two different things: a standard language Common Lisp and widely different languages implementing and extending Common Lisp.

Common Lisp as a language does not require type warnings/errors like that at compile time. An implementation can mostly ignore type declarations. The language also does not really describe what should be done when the compiler does not ignore type declarations and how it should use them to statically check types.

Actual Common Lisp compilers fall in the following groups when it comes to statically declared types:

  1. ignore them mostly. For example the compiler of the Symbolics Lisp Machine falls into this group.

  2. uses declared types mostly for optimization purposes. I'd say CCL falls into this group. I don't think it does much type inference or propagation of type information. I would guess that's also a reason why the compiler is faster than SBCL - it does less.

  3. uses declared types mostly for optimization purposes, but can do type inference and can give type information (for optimization). For example LispWorks falls into this group.

  4. uses declared types for optimization purposes, does type inference, can give type information and regards type declarations as compile-time type assertions. The CMUCL and SBCL compilers are the main members of this group.

So, for implementation of type 2. you best need to declare everything, if you want the compiler to recognize it. Note that Common Lisp provides THE and LOCALLY to write declarations.

If you want to have type declarations as static type assertions and have the compiler check them, you should better use a compiler like SBCL.

A little background on its approach to type declarations can be found in the SBCL Manual: Handling of Types and Type Errors at Compile Time. More background here: The Python Compiler for CMU Common Lisp. Note that the compiler of CMU Common Lisp (and later of SBCL) is called Python - it has nothing to do with the programming language Python. The compiler already had its name (early 1980s) before the language Python (1991) existed.

于 2012-10-01T17:01:39.090 回答
1

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

于 2012-10-18T03:01:36.350 回答