请注意,虽然现有答案是正确的,但禁用警告并不是一个好习惯。在您的情况下,可能没有必要。
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)))
不要评估文件中的任何内容;而是这样做:
(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 使用 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))))
评估整个块不会显示*EVALUATOR-MODE* 同时是:COMPILE 或:INTERPRET 的警告。
当您一个接一个地评估每个表达式(或者可能一个区域接一个区域)时,您所看到的会发生。在那里,编译器无法知道该函数已经存在。消除警告是更糟糕的选择,因为您实际上可能犯了错误。
如果你事先知道一个函数将存在,但不在你的编译单元中(也许它只在运行时定义),你可以声明这个事实,如下:
(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))
...对于不接受任何内容且从不返回值(循环或发出错误信号)的函数。