问题
When I define a function in Common Lisp like this:
(defun foo (n)
(declare (type fixnum n))
(+ n 42))
I expected a call like (foo "a")
to fail right away but it instead fail at the call to +
. Is the declare
form not guarantees static type checking?
回答1:
Type declarations are traditionally meant to be used as guarantees to the compiler for optimization purposes. For type checking, use check-type
(but note that it, too, does the checking at run-time, not at compile-time):
(defun foo (n)
(check-type n fixnum)
(+ n 42))
That said, different Common Lisp implementations interpret type declarations differently. SBCL, for example, will treat them as types to be checked if the safety
policy setting is high enough.
In addition, if you want static checking, SBCL is probably your best bet as well, since its type inference engine warns you about any inconsistencies it encounters. To that end, ftype
declarations can be put to good use:
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
回答2:
Declarations are just hints to the compiler so it can produce more efficient code. In other words, it is not static checking.
来源:https://stackoverflow.com/questions/9521593/common-lisp-type-declarations-not-working-as-expected