常见口臭类型的综合指南 [英] Comprehensive guide on common lisp types

查看:100
本文介绍了常见口臭类型的综合指南的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

也许这个问题太笼统了,不过我会尝试: 是否有关于通用Lisp类型的全面指南?

Maybe this question is too general, nevertheless i'll try: Is there any comprehensive guide on types in common lisp?

我对此主题感到困惑:

为什么在make-array:element-type中声明的非原始类型被提升为t?是否有可能进行真正声明类型的编译时或运行时检查?

Why are non-primitive types declared in make-array's :element-type are promoted to t? Is there any possibility for compile-time or runtime checks of the real declared type?

为什么CLOS插槽定义的类型不能用作约束,而允许将任何类型的值放入插槽?再次,检查如何?

Why are CLOS slot defined types don't work as constraints, allowing to put value of any type into the slot? Again, what about the checks?

declare相同的函数类型声明.它们只是对编译器的优化提示吗?

The same for the functions' types declarations with declare.. Are they just the optimization hints to the compiler?

此外,我是否可以在前面提到的地方使用自定义类型说明符(包括satisfies)进行一些可靠的检查,或者只能将其用于typep e.t.c的显式检查?

Also, can I use custom type specifiers, including satisfies in forementioned places for some robust checks, or they could only be used for explicit checks with typep e.t.c?

如您所见,我脑子有些混乱,因此,非常感谢任何精巧的指南(或一组指南).

As you can see, i've got some mess in my head, so would really appreciate any neat guide (or a set of guides).

我正在使用SBCL,但也很高兴了解实现之间的差异.

I'm on SBCL, but would also be glad to know about differences between implementations.

推荐答案

如果您希望编译器实际执行这些类型,则需要告诉编译器进行安全性优化:

You need to tell the compiler to optimize for safety if you want it to actually enforce the types:

CL-USER> (declaim (optimize (safety 3)))
NIL
CL-USER> (defclass foobar () ())
#<STANDARD-CLASS COMMON-LISP-USER::FOOBAR>
CL-USER> (defun foo (a)
           (make-array 1 :element-type 'foobar
                         :initial-contents (list a)))
FOO
CL-USER> (foo (make-instance 'foobar))
#(#<FOOBAR {1005696CE3}>)
CL-USER> (foo 12)
;=> ERROR
CL-USER> (declaim (ftype (function (integer integer) integer) quux))
(QUUX)
CL-USER> (defun quux (a b)
           (+ a b))
QUUX
CL-USER> (quux 12 12)
24 (5 bits, #x18, #o30, #b11000)
CL-USER> (quux 12 "asd")
;=> ERROR

在运行时检查类型会增加一些开销(特别是如果它是在循环中发生的),并且可能会针对单个值多次执行,因此默认情况下不会这样做.

Checking the types at run-time adds some overhead (especially if it happens in a loop), and may be done multiple times for a single value, so it's not done by default.

(declaim (optimize (safety 3)))

(defun some-predicate-p (a)
  (format t "~&Checking type...")
  (integerp a))

(deftype foo () `(satisfies some-predicate-p))

(defclass bar ()
  ((foo :type foo :initarg :foo)))

(declaim (ftype (function (foo) list) qwerty))
(defun qwerty (foo)
  (loop repeat 10 collecting (make-instance 'bar :foo foo)))

(qwerty 12)
; Checking type...
; Checking type...
; Checking type...
; Checking type...
; Checking type...
; Checking type...
; Checking type...
; Checking type...
; Checking type...
; Checking type...
; Checking type...
;=> (#<BAR {1003BCA213}> #<BAR {1003BCA263}> #<BAR {1003BCA2B3}>
;    #<BAR {1003BCA303}> #<BAR {1003BCA353}> #<BAR {1003BCA3A3}>
;    #<BAR {1003BCA3F3}> #<BAR {1003BCA443}> #<BAR {1003BCA493}>
;    #<BAR {1003BCA4E3}>)

如果您希望函数始终检查场所的类型,而不考虑优化设置,则应使用

If you want a function to always check the type of a place, regardless of the optimization settings, you should use CHECK-TYPE manually.

这篇关于常见口臭类型的综合指南的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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