在 common-lisp 中,类型之间的关系是如何定义的?
在玩 Lisp 时我注意到以下几点:
(subtypep 'string '(array character)) ==> NIL, T
(subtypep '(array character) 'string) ==> NIL, T
while
(typep (make-string x) '(array character)) ==> T
(typep (make-array x :element-type :character) 'string) ==>T
对于任何 x 值。
这意味着“subtypep”表示“字符串”和“(数组字符)是两种不同的类型,而“typep”表示一种类型的任何实例也是另一种类型的实例 (1)
除非(1) 不正确-请举例-为什么会发生这种情况?我发现很难理解,因为我假设类型在概念上不能没有实例而存在,也就是说,它是由实例定义的:它是具有一组特定属性的对象的类(在数学意义上)。这是正确的吗?
编辑:正确指出 (数组字符)
不一定是 string
的子类型,原因很简单,因为存在多维字符数组。但我仍然无法想象一个没有 (数组字符)
类型的 string
实例。
While playing in Lisp i noticed the following:
(subtypep 'string '(array character)) ==> NIL, T
(subtypep '(array character) 'string) ==> NIL, T
while
(typep (make-string x) '(array character)) ==> T
(typep (make-array x :element-type :character) 'string) ==>T
for any value of x.
Which means that "subtypep" says that 'string and '(array character) are two distinct types while "typep" says that any instance of the one type is also an instance of the other (1)
Unless (1) is not true -please give example-, why does this happen? I find it difficult to grasp because I assume that a type cannot conceptually exist without its instances, that is, it is defined by its instances: It is the class (in the mathematical sense) of objects that have a specific set of properties. Is this correct?
EDIT: As correctly pointed (array character)
is not necessarily a subtype of string
, for the simple reason of the existence of multi-dimensinal arrays of characters. But I still cant imagine an instance of string
that has not a type of (array character)
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
请参阅 http://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)
中的数组Common Lisp 是可变的,而不是试图假装它们是协变或逆变并添加复杂的动态检查,CL 中的数组是不变的。因此,除非它们相同,否则
(数组字符1)
和(数组base-char 1)
之间不存在子类型关系。程序不应存储非基数。后者中的字符,并且程序可以从前者中读取非基字符,这有助于记住,虽然某些编译器使用类型声明是为了安全,但它们的主要目标是类型化。数组已映射(升级)为一组特殊处理的数组元素类型。这些特殊的数组类型必须形成一个格(确保我们能够合理地找到最具体的特殊类型),但仍然没有子类型关系。
See http://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)
Arrays in Common Lisp are mutable. Instead of attemping to pretend they're covariant or contravariant and adding complex dynamic checks, arrays in CL are invariant. Thus, unless they are the same, there is no subtyping relationship between
(array character 1)
and(array base-char 1)
. Programs shouldn't store non-base characters in the latter, and programs could read a non-base character from the former.Array upgrading causes further confusions for newcomers. It helps to keep in mind that, while some compilers use type declarations for safety, their primary goal is performance. Typed arrays are mapped (upgraded) to a set of specially-handled array element types. These specialised array types must form a lattice (ensuring that we can sanely find the most specific specialised type), but there still no subtyping relationship.
这是一个实现问题:
It is an implemntaiton issue:
实际上,这是您的实现中的一些奇怪的事情。 (可能与某些优化有关)。
例如,在 SBCL 中,如果您
(describe 'string)
,您将得到STRING 命名一个原始类型说明符:(未记录)
。有趣的是,对于base-string
来说它是相同的,但是:Actually, this is some quirky thing in your implementation. (Possibly connected to some optimization).
For example in SBCL, if you
(describe 'string)
, you'll getSTRING names a primitive type-specifier: (undocumented)
. The interesting thing is that forbase-string
its the same, but:尝试:
在SBCL和其他实现中了解。 (vector nil) 是字符串子类型的要求遵循标准,即使基本字符和字符在实现中是等效的。
Try:
in SBCL and other implementations to understand. The requirement of (vector nil) being a subtype of string follows from the standard, even if base-char and character are equivalent in an implementation.