常见的Lisp类型声明无法正常工作 [英] Common Lisp type declarations not working as expected

查看:113
本文介绍了常见的Lisp类型声明无法正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我在Common Lisp中定义这样的函数时:

When I define a function in Common Lisp like this:

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

我希望像(foo "a")这样的呼叫会立即失败,但是在呼叫+时会失败. declare形式不能保证静态类型检查吗?

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?

推荐答案

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

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))

也就是说,不同的Common Lisp实现对类型声明的解释不同. SBCL,例如会将safety策略设置足够高.

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.

此外,如果要进行静态检查,SBCL可能也是最好的选择,因为它的类型推断引擎会警告您遇到的任何不一致之处.为此,可以很好地使用ftype声明:

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

这篇关于常见的Lisp类型声明无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆