Common lisp 特殊声明

Common lisp 特殊声明,common-lisp,sbcl,Common Lisp,Sbcl,SBCL生成关于未定义函数的虚假样式警告。(函数是在文件后面定义的。)我想一劳永逸地解决这个问题。幸运的是,有一种方法可以做到这一点: (declaim (sb-ext:muffle-conditions style-warning)) 不利的一面是,出于明显的原因,CCL会在包含上述内容的程序上呕吐。我尝试用一个条件来解决这个问题: (#+sbcl (declaim (sb-ext:muffle-conditions style-warning))) 但现在SBCL不高兴了:“非法函数调用

SBCL生成关于未定义函数的虚假样式警告。(函数是在文件后面定义的。)我想一劳永逸地解决这个问题。幸运的是,有一种方法可以做到这一点:

(declaim (sb-ext:muffle-conditions style-warning))
不利的一面是,出于明显的原因,CCL会在包含上述内容的程序上呕吐。我尝试用一个条件来解决这个问题:

(#+sbcl (declaim (sb-ext:muffle-conditions style-warning)))
但现在SBCL不高兴了:“非法函数调用”


如何将这样的声明放入可移植程序中?

省略外圆括号:

#+sbcl (declaim (sb-ext:muffle-conditions style-warning))
当您使用
declaim
时,我假设声明出现在编译单元的顶层。如果需要对多个顶级语句进行分组,可以使用
progn
将它们全部打包(这不会改变“顶级”属性)

SBCL抱怨的原因是,它的读者阅读

((declaim (sb-ext:muffle-conditions style-warning)))
()
(由于存在
:SBCL
功能),这只是一个语法错误。CCL没有抱怨,因为它的读者阅读

((declaim (sb-ext:muffle-conditions style-warning)))
()

这只是拼写
nil

的另一种方式。请注意,尽管现有答案是正确的,但禁用警告不是一种好做法。在你的情况下,这可能是没有必要的

CommonLisp有一个编译单元的概念,其中多个定义被分组在一起。这使编译器/解释器有机会处理函数之间的交叉引用(例如,解释器可以收集警告,并只保留那些以后找不到的警告)

例如,在文件
#p”/tmp/foo.pl“
中:

不要评估文件中的任何内容;相反,你应该:

(compile-file #P"/tmp/foo.pl")

; compiling (DEFUN MUT-REC-FOO ...)
; compiling (DEFUN MUT-REC-BAR ...)

; /tmp/foo.fasl written
; compilation finished in 0:00:00.002
没有警告。然后,您可以调用
(load#P)/tmp/foo.fasl“
,在当前的lisp环境中获得这些定义,而不发出警告。 通常,ASDF和扩展名Quicklisp使用
编译文件
,因此,只要将文件捆绑到系统中,问题就会消失

您还可以执行以下操作:

(with-compilation-unit ()
  (defun mut-rec-foo/bis (x)
    (when (plusp x)
      (mut-rec-bar/bis (1- x))))

  (defun mut-rec-bar/bis (x)
    (print x)
    (mut-rec-foo/bis (1- x))))
对于
*EVALUATOR-MODE*
同时是
:COMPILE
:explain
,对整个块进行求值时不会显示任何警告

当您一个接一个地计算每个表达式(或者一个区域接一个区域)时,会发生您看到的情况。在那里,编译器无法知道函数已经存在。使警告静音是更糟糕的选择,因为您可能实际上犯了错误

如果您事先知道某个函数将存在,但不在编译单元中(可能仅在运行时定义),则可以声明该事实,如下所示:

(declaim (ftype function my-function))
上面说,
my function
必须假定是
fbound
到类型为
function
的对象。您还可以通过细化您声称的功能类型来提供更多信息:

(declaim (ftype (function (number) (values string &optional)) num-to-string))
。。。对于接受数字并只返回一个值的函数,一个字符串

(declaim (ftype (function () nil) forever-loop))
。。。对于不接受任何内容且从不返回值(循环或发出错误信号)的函数