2012-03-01 8 views
4

私はこのようなCommon Lispでは関数を定義する場合:Common Lispの型宣言が機能していない予想通り

(defun foo (n) 
    (declare (type fixnum n)) 
    (+ n 42)) 

私は(foo "a")のような呼び出しがすぐに失敗すると予想しかし、それは代わりに+への呼び出しで失敗します。 declareフォームは静的型検査を保証していませんか?

答えて

13

型宣言は、従来、最適化の目的でコンパイラに保証として使用されていました。型チェックのために、check-typeを使用します(しかし、それは、あまりにも、実行時ではなく、コンパイル時にチェックしないことに注意してください):

(defun foo (n) 
    (check-type n fixnum) 
    (+ n 42)) 

異なるCommon Lispの実装が異なっ型宣言を解釈し、言いました。たとえば、safetyのポリシー設定が十分に高い場合は、SBCL。たとえば、will treat them as types to be checked

また、静的なチェックが必要な場合は、型推論エンジンが遭遇する矛盾を警告するので、おそらくSBCLが最適です。その目的のために、ftype宣言を有効に使用することができます。

CL-USER(1): (declaim (ftype (function (string) string) bar)) 

CL-USER(2): (defun foo (n) 
       (declare (type fixnum n)) 
       (bar n)) 
; in: DEFUN FOO 
;  (BAR N) 
; 
; caught WARNING: 
; Derived type of N is 
;  (VALUES FIXNUM &OPTIONAL), 
; conflicting with its asserted type 
;  STRING. 
; See also: 
;  The SBCL Manual, Node "Handling of Types" 
; 
; compilation unit finished 
; caught 1 WARNING condition 

FOO 
-1

宣言はコンパイラにとってのヒントに過ぎず、より効率的なコードを生成できます。つまり、静的検査ではありません。

関連する問題