2012-10-01 75 views
2

我在尋求改進我收到的編譯器警告的質量和數量 - 在Common Lisp中是否有一種方法可以在聲明的類型和實例上包含類型謂詞 - 實現特定的回答 沒問題,我很想看看它是如何完成的,如果有人在做。類型謂詞遍佈類型

編譯覆銅板如下:

(defun non-list (o) 
    (not (listp o))) 

(deftype non-list() 
    '(satisfies non-list)) 

(defun example (a) 
    (list a)) 

(declaim (ftype (function (non-list) list) example)) 

(defun hmm() 
    (declare (optimize (debug 3) (safety 3))) 
    (let ((a '(a b c)) 
    (b '(d e f))) 
    (declare (type list a)) 
    (example '(g h i)) 
    (example a) 
    (example b))) 

我會得到一個編譯器在第一次調用警示example - 提供可針對satisfies要檢驗的 實例之一。這很好,在調試設置下,我會得到一個很好的運行時錯誤。我想知道是,如果我可以寫類似如下:

(defun non-list-typep (type) 
    (not (subtypep type 'list))) 

並以某種方式整合它,這樣至少第二次調用 - (example a)將在警告編譯時間作爲其聲明的類型list會失敗謂詞non-list-typep

乾杯!

回答

6

有點背景

有兩種不同的東西:一個標準的語言Common Lisp的和在執行和延長Common Lisp的廣泛不同的語言。

Common Lisp作爲一種語言,在編譯時不需要類型警告/錯誤。一個實現可以大部分忽略類型聲明。該語言也沒有真正描述當編譯器不忽略類型聲明時應該做什麼以及如何使用它們來靜態檢查類型。

實際的Common Lisp編譯器分爲以下組,當涉及到靜態聲明的類型:

  1. 忽略它們居多。例如,Symbolics Lisp Machine的編譯器屬於這個組。

  2. 主要用於優化目的的聲明類型。我想說CCL屬於這個羣體。我不認爲它會對類型信息進行類型推斷或傳播。我猜想這也是編譯器比SBCL速度更快的原因 - 它少了。

  3. 使用聲明的類型主要用於優化目的,但可以做類型推斷並可以提供類型信息(用於優化)。例如LispWorks屬於這個組。

  4. 使用聲明類型用於優化目的,類型推斷,可以給出類型信息並將類型聲明視爲編譯時類型聲明。 CMUCL和SBCL編譯器是該組的主要成員。

因此,對於類型2的實現,如果希望編譯器識別它,則最好需要聲明所有內容。請注意,Common Lisp提供了THELOCALLY來編寫聲明。

如果您希望將類型聲明作爲靜態類型聲明並讓編譯器檢查它們,則最好使用類似SBCL這樣的編譯器。

有關其類型聲明方法的一些背景信息,請參見SBCL手冊:Handling of TypesType Errors at Compile Time。更多背景:The Python Compiler for CMU Common Lisp。請注意,CMU Common Lisp的編譯器(以及SBCL的更高版本)被稱爲Python - 它與編程語言Python無關。在語言Python(1991)存在之前,編譯器已經有了它的名字(20世紀80年代初)。

+0

謝謝,現在看看這些。 – Lex

1

另一種方法是在Common Lisp上實現類型檢查語言,如Qi。我想它是以defun的一對智能宏開始的,以解決你所面臨的問題。

+0

是的,這是可行的,但我真的更感興趣的是增加CL,而不是轉向全新的語言。我認爲在某些時候我可能會試圖將這個特性轉化爲CCL或者SBCL,但是我們已經在他們的內部進行了一些探索,在找到正確的方法之前,我會學習很多東西。希望它不應該太難:) – Lex