Search code examples
lispcommon-lispsbclclisp

lisp: required argument to defun not a symbol


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.


Solution

  • 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.