公共Lisp类型声明未按预期工作

公共Lisp类型声明未按预期工作,lisp,common-lisp,static-typing,Lisp,Common Lisp,Static Typing,当我在Common Lisp中定义函数时,如下所示: (defun foo (n) (declare (type fixnum n)) (+ n 42)) 我期望像(foo“a”)这样的调用立即失败,但它在调用+时失败。declare表单不保证静态类型检查吗?声明只是对编译器的提示,因此它可以生成更高效的代码。换句话说,它不是静态检查。类型声明传统上是用来作为编译器优化目的的保证。对于类型检查,请使用检查类型(但请注意,它也在运行时进行检查,而不是在编译时进行检查): 也就是说,不同的

当我在Common Lisp中定义函数时,如下所示:

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

我期望像
(foo“a”)
这样的调用立即失败,但它在调用
+
时失败。
declare
表单不保证静态类型检查吗?

声明只是对编译器的提示,因此它可以生成更高效的代码。换句话说,它不是静态检查。

类型声明传统上是用来作为编译器优化目的的保证。对于类型检查,请使用
检查类型
(但请注意,它也在运行时进行检查,而不是在编译时进行检查):

也就是说,不同的公共Lisp实现对类型声明的解释不同。SBCL,例如,如果
安全
策略设置足够高

此外,如果您想要静态检查,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
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