SBCL生成关于未定义函数的虚假样式警告.(这些函数是在文件的后面定义的.)我想一劳永逸地解决这个问题.幸运的是,有一种方法可以做到这一点:
(declaim (sb-ext:muffle-conditions style-warning))
Run Code Online (Sandbox Code Playgroud)
缺点是CCL出于显而易见的原因,对包含上述内容的程序进行了限制.我尝试用条件解决这个问题:
(#+sbcl (declaim (sb-ext:muffle-conditions style-warning)))
Run Code Online (Sandbox Code Playgroud)
但现在SBCL不高兴:"非法打电话".
你如何将这样的声明放入便携式程序?
请注意,虽然现有答案是正确的,但禁用警告不是一个好习惯.在您的情况下,可能没有必要.
Common Lisp有一个编译单元的概念,其中多个定义组合在一起.这使编译器/解释器有机会处理函数之间的交叉引用(例如,解释器可以收集警告并仅保留稍后未找到的警告).
例如,在文件中#P"/tmp/foo.pl":
(defun mut-rec-foo (x)
(when (plusp x)
(mut-rec-bar (1- x))))
(defun mut-rec-bar (x)
(print x)
(mut-rec-foo (1- x)))
Run Code Online (Sandbox Code Playgroud)
不要评估文件中的任何内容; 改为做:
(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
Run Code Online (Sandbox Code Playgroud)
没有警告.然后,您可以(load #P"/tmp/foo.fasl")在没有警告的情况下调用当前lisp环境中的定义.通常,ASDF和扩展名Quicklisp使用COMPILE-FILE,因此只要将文件捆绑到系统中,问题就会消失.
你也可以这样做:
(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))))
Run Code Online (Sandbox Code Playgroud)
评估整个块显示没有警告*EVALUATOR-MODE*同时:COMPILE或:INTERPRET.
当您逐个评估每个表达式(或者可能是另一个表达式之后的一个区域)时,您所见证的情况会发生.在那里,编译器无法知道该函数已经存在.沉默警告是更糟糕的选择,因为您实际上可能犯了错误.
如果你事先知道的功能会存在,但不是在你的编译单元(也许它只是在运行时所定义的),则可以朗诵这一事实,具体如下:
(declaim (ftype function my-function))
Run Code Online (Sandbox Code Playgroud)
上面说的my-function必须假设是fbound一个类型的对象function.您还可以通过改进您声称的功能来提供更多信息:
(declaim (ftype (function (number) (values string &optional)) num-to-string))
Run Code Online (Sandbox Code Playgroud)
...对于接受数字并且只返回一个值的函数,一个字符串.
(declaim (ftype (function () nil) forever-loop))
Run Code Online (Sandbox Code Playgroud)
...对于一个不接受任何东西并且永远不会返回值的函数(循环或发出错误信号).
省略外面的括号:
#+sbcl (declaim (sb-ext:muffle-conditions style-warning))
Run Code Online (Sandbox Code Playgroud)
正如您所使用的那样declaim,我假设声明出现在编译单元的顶层.如果您需要对多个顶级语句进行分组,则可以使用a来包装它们progn(这不会更改"顶级"-ness).
SBCL抱怨的原因是它的读者读到了
((declaim (sb-ext:muffle-conditions style-warning)))
Run Code Online (Sandbox Code Playgroud)
(因为该:SBCL功能存在),这只是一个语法错误.CCL没有抱怨,因为它的读者读到了
()
Run Code Online (Sandbox Code Playgroud)
这只是另一种拼写方式nil.