【问题标题】:Common Lisp: Trouble with * in function type-specifierCommon Lisp:函数类型说明符中 * 的问题
【发布时间】:2026-01-01 20:05:01
【问题描述】:

几周后,我意识到我在使用与类型说明符有关的特定构造时遇到了麻烦。 首先,我使用的是从源代码编译的 SBCL 2.1.9,它“显然通过了所有测试”。

问题出在这里:当我尝试使用此表单为函数指定类型时

(declaim (ftype (function (*) int) foo))

这是 SBCL 告诉我的

debugger invoked on a SIMPLE-ERROR in thread
#<THREAD "main thread" RUNNING {1001870303}>:
  * is not permitted as an argument to the FUNCTION type specifier

如果不是出于以下几个原因,这很可能是完全正常的:

  • 在另一台装有 SBCL 2.1.8 的机器上使用完全相同的表单时,此表单完全有效
  • 规范似乎并没有禁止这种结构,尽管很难说。例如,sb-kernel中有一堆代码,即types.lisp文件(完全写在SB-KERNEL包中),专门用于捕捉类型说明符中无效的*符号。如果不详细阅读这些功能,很难判断这是否正常。
  • 很多人,比我有很多很多的经验,在他们的项目中使用这个构造。最近尝试手动编译它们给我带来了很多麻烦,因为 SBCL 不允许我编译这些表单。例如,我针对这个问题为 Nyxt 浏览器打开了一个 issue,但我仍然无法编译已成功用于制作大量游戏的游戏引擎 cl-bodge(因此,此类错误应该是早就过去了)

所以,我有几个问题:

  • 一劳永逸地,有问题的形式是有效的 Common Lisp 吗?
  • 如果不是,为什么这么多人,包括一些最了解 CL 的人,使用它(似乎没有任何问题)?
  • 如果是(我很确定是),我是否有任何理由观察到这种行为,即使在重新编译 SBCL 并通过所有测试之后也是如此?
  • 您对我如何解决这个问题有任何想法,因此我不再需要在我尝试编译的所有库中手动将这种形式的所有 ftype 声明重写为 (ftype (function (t) bar) foo) ?

提前致谢!

【问题讨论】:

  • 您可以尝试使用 Comby 规则/脚本来自动重写声明:comby.dev 它比正则表达式更好,因为它为我们处理括号和 cmets。 (& Nyxt 的人对 CL 类型声明非常陌生;)(与他们一起工作))

标签: lisp common-lisp sbcl


【解决方案1】:

(function (*) ...) 从未合法 CL:见the hyperspec。 SBCL 可能已经接受了它,尽管我不知道它的含义(可能与(function (&amp;rest t) ...) 相同?)。如果“一些最了解 CL 的人”一直在使用,那么,我不会推测他们对 CL 的了解,但我强烈建议他们要么修复他们的声明,要么根据接受它们的实现对它们进行条件化.

【讨论】: