2017-09-28 89 views
1

當從CLISP移植遺留代碼的SbCl,我遇到語法這引起由該代碼而沒有明顯的錯誤運行在CLISP所示的問題:口齒不清:必需的參數,以defun定義不是一個符號

(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

+0

你確定它是'defun'而不是'defmethod'嗎? – rsm

+0

@rsm是的,它是'defun'。你看到的代碼就像我運行它一樣,而輸出完全按照它的結果。 –

回答

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。這個功能是CLISP在十三年前在2004年夏季推出的,我想知道哪個軟件包使用它。

+0

發情!請提出兩個問題:(1)CLISP是否忽略了被視爲錯誤或特徵的類型聲明?和(2)我欠你另一個zorkmid嗎? –

+1

「某個功能是一個擁有終身職位的錯誤」。在這種情況下,這是一個原始設計決定。此外,CLISP行爲完全符合標準。如果你想了解更多細節,請提出一個單獨的問題。 ;-) – sds

+0

當涉及到所有優化提示都可以忽略的事實時,CL非常令人困惑。因此,人們不能真正依靠它們。 – Sylwester