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

时间:2017-09-28 15:01:02

标签: lisp common-lisp sbcl clisp

将遗留代码从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,但不是urllib

1 个答案:

答案 0 :(得分:7)

您依赖于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中引入的。我想知道哪个包使用它。