lisp:defun 的必需参数不是符号

lisp: required argument to defun not a symbol

将遗留代码从 clisp 移植到 sbcl 时,我遇到了引发问题的语法,该代码在 clisp 中运行时没有明显错误:

(defun foo ((alpha integer))
  (princ (type-of alpha))
  (princ " ")
  (prin1 alpha)
  (terpri))
(foo 3)
(foo 3.5)
(foo (list "beta" "gamma" "delta"))
;;; output follows ;;;
(INTEGER 0 281474976710655) 3
SINGLE-FLOAT 3.5
CONS ("beta" "gamma" "delta")

显然第一行的integer纯粹是注释修饰。

sbcl,遇到#'foo的相同定义,报错:

Required argument is not a symbol: (ALPHA INTEGER)

这里integer的目的到底是什么?这两种行为中的哪一种(如果有)符合标准?

编辑:

有问题的遗留代码是某种(古老的)cl-lex,但不是 this one

您依赖于 CLISP 扩展 CUSTOM:*DEFUN-ACCEPT-SPECIALIZED-LAMBDA-LIST*:

(defun foo ((alpha integer)) ; non-standard
  ...)

相当于

(defun foo (alpha) ; ANSI CL conformant
  (declare (type integer alpha))
  ...)

custom:*defun-accept-specialized-lambda-list*t 时。

此扩展使 defun 有点像defmethod。 但是,CLISP ignores type declarations, 所以这种代码修饰的唯一作用是记录程序员的意图。

SBCL 不支持这个扩展,所以你会得到同样的错误 你将从 CLISP 中获得 custom:*defun-accept-specialized-lambda-list* 设置为 nil:

*** - FUNCTION: (ALPHA INTEGER) is not a symbol

PS。这个特性是在13年前的2004年夏天在CLISP中引入的。我想知道哪个包使用它。