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

Bil*_*osa 1 lisp clisp sbcl common-lisp

当将遗留代码从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")
Run Code Online (Sandbox Code Playgroud)

显然integer在第一行纯粹作为评论装饰.

sbcl,遇到相同的定义#'foo,抱怨:

Required argument is not a symbol: (ALPHA INTEGER)
Run Code Online (Sandbox Code Playgroud)

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

编辑:

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

sds*_*sds 7

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

(defun foo ((alpha integer)) ; non-standard
  ...)
Run Code Online (Sandbox Code Playgroud)

相当于

(defun foo (alpha) ; ANSI CL conformant
  (declare (type integer alpha))
  ...)
Run Code Online (Sandbox Code Playgroud)

custom:*defun-accept-specialized-lambda-list*t.

这个扩展defun 看起来有点像defmethod.但是,CLISP 忽略了类型声明,因此这个代码修饰的唯一影响是程序员意图的文档.

SBCL不支持此扩展,因此您从CLISP获得的错误与 custom:*defun-accept-specialized-lambda-list*设置为nil:

*** - FUNCTION: (ALPHA INTEGER) is not a symbol
Run Code Online (Sandbox Code Playgroud)

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

  • 允许实现忽略类型声明,请参见[此处在ANSI CL中](http://www.ai.mit.edu/projects/iiip/doc/CommonLISP/HyperSpec/Body/sec_3-3-1.html).如果您希望在所有实施和所有[安全](http://www.ai.mit.edu/projects/iiip/doc/CommonLISP/HyperSpec/Body/dec_optimize.html)设置中保持类型检查,请使用[检查-type](http://www.ai.mit.edu/projects/iiip/doc/CommonLISP/HyperSpec/Body/mac_check-type.html)宏. (3认同)