When porting legacy code from clisp to sbcl, I encountered syntax which raised a problem illustrated by this code which runs without apparent error in 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")
Apparently integer
in the first line acts purely as commentative decoration.
sbcl, encountering the same definition of #'foo
, complains:
Required argument is not a symbol: (ALPHA INTEGER)
What exactly is the purpose of integer
here? Which of these two behaviors (if either) is standards compliant?
EDIT:
The legacy code in question is some (ancient) sort of cl-lex
, but not this one.
You are relying on a CLISP extension CUSTOM:*DEFUN-ACCEPT-SPECIALIZED-LAMBDA-LIST*
:
(defun foo ((alpha integer)) ; non-standard
...)
is equivalent to
(defun foo (alpha) ; ANSI CL conformant
(declare (type integer alpha))
...)
when custom:*defun-accept-specialized-lambda-list*
is t
.
This extension makes defun
look a little bit like defmethod
.
However, CLISP ignores type declarations,
so the only effect this code decoration has is documentation of the programmer's intent.
SBCL does not support this extension, so you get the same error from it
that you would get from CLISP with
custom:*defun-accept-specialized-lambda-list*
set to nil
:
*** - FUNCTION: (ALPHA INTEGER) is not a symbol
PS. This feature was introduced in CLISP 13 years ago in the summer of 2004. I wonder which package uses it.