【问题标题】:In common-lisp how is the relation between types defined?在 common-lisp 中,类型之间的关系是如何定义的?
【发布时间】:2011-10-20 14:56:50
【问题描述】:

在玩 Lisp 时,我注意到以下几点:

(subtypep 'string '(array character)) ==> NIL, T
(subtypep '(array character) 'string) ==> NIL, T

同时

(typep (make-string x) '(array character)) ==> T
(typep (make-array x :element-type :character) 'string) ==>T

对于任何 x 值。

这意味着“subtypep”表示'string和'(数组字符)是两种不同的类型,而“typep”表示一种类型的任何实例也是另一种类型的实例( 1)

除非 (1) 不正确-请举例说明-,为什么会发生这种情况?我觉得很难理解,因为我假设一个类型在概念上不能没有它的实例而存在,也就是说,它是由它的实例定义的:它是具有一组特定属性的对象的类(在数学意义上)。它是否正确?

编辑:正如正确指出的那样,(array character) 不一定是string 的子类型,原因很简单,因为存在多维字符数组。但我仍然无法想象没有(array character) 类型的string 实例。

【问题讨论】:

    标签: types lisp common-lisp


    【解决方案1】:

    http://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)

    Common Lisp 中的数组是可变的。 CL 中的数组是不变的,而不是试图假装它们是协变或逆变的并添加复杂的动态检查。因此,除非它们相同,否则(array character 1)(array base-char 1) 之间没有子类型关系。程序不应该在后者中存储非基本字符,程序可以从前者中读取非基本字符。

    阵列升级会给新手带来更多的困惑。请记住,虽然一些编译器出于安全考虑使用类型声明,但它们的主要目标是性能。类型化数组映射(升级)到一组特殊处理的数组元素类型。这些特殊的数组类型必须形成一个格子(确保我们可以理智地找到最特殊的特殊类型),但仍然没有子类型关系。

    【讨论】:

      【解决方案2】:

      这是一个实现问题:

      ccl e$ rlwrap ./dx86cl64
      Loading ~/ccl-init.lisp
      Welcome to Clozure Common Lisp Version 1.7-dev-r14614M-trunk  (DarwinX8664)!
      ? (subtypep 'string '(array character))
      T
      T
      ? 
      

      【讨论】:

        【解决方案3】:

        实际上,这在您的实现中有些古怪。 (可能与一些优化有关)。

        例如在 SBCL 中,如果您 (describe 'string),您将获得 STRING names a primitive type-specifier: (undocumented)。有趣的是base-string 是一样的,但是:

        (subtypep 'base-string 'array) => T
        (subtypep 'base-string '(array base-char)) => T
        (subtypep 'string 'array) => T
        (subtypep 'string '(array character)) => NIL
        (subtypep 'string '(array base-char)) => NIL
        (subtypep 'string '(array standard-char)) => NIL
        (subtypep 'string '(array extended-char)) => NIL
        

        【讨论】:

        • Base-string 是 (array base-char) 的子类型。是什么阻止字符串成为(数组字符)的子类型?
        • 获得这个问题答案的最佳地点可能是 sbcl-devel 邮件列表。这可能是优化或错误。
        【解决方案4】:

        试试:

        (subtypep '(vector nil) 'string)
        

        在 SBCL 和其他实现中了解。 (vector nil) 作为 string 的子类型的要求遵循标准,即使 base-char 和 character 在实现中是等价的。

        【讨论】:

          猜你喜欢
          • 2021-03-17
          • 1970-01-01
          • 1970-01-01
          • 2012-01-16
          • 2023-03-18
          • 1970-01-01
          • 2011-12-24
          • 2020-09-25
          • 2012-07-12
          相关资源
          最近更新 更多