Common Lisp で次のように関数を定義すると:
(defun foo (n)
(declare (type fixnum n))
(+ n 42))
(foo "a")
like の呼び出しがすぐに失敗することを期待していましたが、代わりに への呼び出しで失敗し+
ます。フォームはdeclare
静的型チェックを保証していませんか?
Common Lisp で次のように関数を定義すると:
(defun foo (n)
(declare (type fixnum n))
(+ n 42))
(foo "a")
like の呼び出しがすぐに失敗することを期待していましたが、代わりに への呼び出しで失敗し+
ます。フォームはdeclare
静的型チェックを保証していませんか?
型宣言は伝統的に、最適化目的でコンパイラへの保証として使用されることを意図しています。型チェックには、次を使用しますcheck-type
(ただし、これもコンパイル時ではなく実行時にチェックを行うことに注意してください)。
(defun foo (n)
(check-type n fixnum)
(+ n 42))
つまり、Common Lisp の実装が異なれば、型宣言の解釈も異なります。たとえば、SBCL は、ポリシー設定が十分に高い場合にチェックするタイプとしてそれらを扱います。safety
さらに、静的チェックが必要な場合は、おそらく 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
宣言は、コンパイラがより効率的なコードを生成できるようにするための単なるヒントです。つまり、静的チェックではありません。