如何在常见的lisp中定义函数之前定义它?

时间:2016-11-28 04:03:10

标签: lisp common-lisp

我将在SBCL中使用以下代码示例获得有关f2的未定义函数警告。 我是否有可能首先声明f2,就像在C中一样,以避免警告。 我用Google搜索,没有任何线索。

(defun f ()
  (print (f2)))

(defun f2 ()
  (print "f2"))

4 个答案:

答案 0 :(得分:6)

如果在单个compilation unit中定义它之前使用该函数,例如同一个文件,那么编译器将不会抱怨未定义的函数(plain {{3}仍然可以,所以首先编译你的代码!)

否则,您可以load declaim

(declaim (ftype (function () t) f2)

意味着f2不接受任何参数并返回ftype类型的value

但是,在已经加载定义的情况下编译使用该函数的文件更有意义。您可以(并且应该!)使用t作为特定于Lisp的asdf:指定依赖项,以便编译器在编译其用户时具有所有函数的定义。

答案 1 :(得分:4)

如果函数在同一个文件中,编译器将不会发出警告。

示例SBCL:

countThis(something)

答案 2 :(得分:4)

您不必将函数放入Common Lisp中的同一文件中,以使它们位于同一个编译单元中。

这样做是一种反模式;当然,大型程序是由模块构建的,其中大多数模块调用另一个模块中的函数。您无法将整个程序滚动到单个物理模块中以避免发出警告。

Lisp有一种机制,通过这种机制,一组编译被视为一个单独的编译单元:with-compilation-unit宏:

(with-compilation-unit
  (compile-file "file-f")
  (compile-file "file-f2"))

如果您使用ASDF构建系统,我似乎记得它为您提供了with-compilation-unit围绕系统的所有文件。

这种方法有助于消除那些被推迟的警告。也就是说,如果实现警告未定义的标识符,但延迟这样做直到编译单元结束,那么如果使用此宏,延迟将延长到编译总结束单位跨越多个文件。

当延迟发出有关未定义标识符的警告时,目的是消除这些警告。如果先前未定义的函数的定义出现在翻译单元结束之前,则可以抑制警告。此宏允许一个文件中的定义抑制另一个文件中的延迟警告。

如果实施没有推迟警告,那么宏将无济于事。

答案 3 :(得分:1)

只需更改你的defun的顺序即可。首先,定义f2而不是f。