私はこのようなCommon Lispでは関数を定義する場合:Common Lispの型宣言が機能していない予想通り
(defun foo (n)
(declare (type fixnum n))
(+ n 42))
私は(foo "a")
のような呼び出しがすぐに失敗すると予想しかし、それは代わりに+
への呼び出しで失敗します。 declare
フォームは静的型検査を保証していませんか?
私はこのようなCommon Lispでは関数を定義する場合:Common Lispの型宣言が機能していない予想通り
(defun foo (n)
(declare (type fixnum n))
(+ n 42))
私は(foo "a")
のような呼び出しがすぐに失敗すると予想しかし、それは代わりに+
への呼び出しで失敗します。 declare
フォームは静的型検査を保証していませんか?
型宣言は、従来、最適化の目的でコンパイラに保証として使用されていました。型チェックのために、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
宣言はコンパイラにとってのヒントに過ぎず、より効率的なコードを生成できます。つまり、静的検査ではありません。