在 Common Lisp (ClozureCL) 中,什么表达式会产生类型为“(SIMPLE-ARRAY ARRAY (5 3 *))”的值?

In Common Lisp (ClozureCL), what expression yields a value of type `(SIMPLE-ARRAY ARRAY (5 3 *))`?

我正在尝试使用 ClozureCL 学习 CL,并且正在 Google's Lisp koans

剧透警告:我给出了一个框架我的问题的答案,因为如果我不这样做,提交的答案可能没有目标。


此处的代码显示通过的 x 值。

(define-test test-guess-that-type!
  (let ((x '(SIMPLE-ARRAY ARRAY (5 3 *))))
    (assert-true (subtypep x '(SIMPLE-ARRAY T (* 3 *))))
    (assert-true (subtypep x '(SIMPLE-ARRAY T (5 * *))))
    (assert-true (subtypep x '(SIMPLE-ARRAY ARRAY *)))
    (assert-true (typep (make-array '(5 3 9) :element-type 'STRING ) x))
    (assert-true (typep (make-array '(5 3 33) :element-type 'VECTOR ) x))))

除了类型表示法中使用的模式之外,我觉得我没有学到很多东西。我想看看我是否可以使用 (type-of ...) 形式的 x 值通过测试,以便我可以通过示例将实际值与类型相关联。

也就是说,这是我目前没有根据的猜测。我用 ; <!> 标记的断言因我为 x.

选择的第一个值而失败
(define-test test-guess-that-type!
  (let ((x (type-of (make-array '(5 3 33) :element-type 'VECTOR))))
    (assert-true (subtypep x '(SIMPLE-ARRAY T (* 3 *))))
    (assert-true (subtypep x '(SIMPLE-ARRAY T (5 * *))))
    (assert-true (subtypep x '(SIMPLE-ARRAY ARRAY *)))
    (assert-true (typep (make-array '(5 3 9) :element-type 'STRING ) x)) ; <!>
    (assert-true (typep (make-array '(5 3 33) :element-type 'VECTOR ) x))))

我的问题是:如果您被限制使用 (type-of <val>) 什么 <val> 解决了 koan

到目前为止的观察:

我认为没有解决方案。实际上,您可能会在某些 CL 实现中找到解决方案,但不能保证。在大多数情况下,TYPE-OF 的规范并未详细说明类型说明符 returned,仅要求

(typep object (type-of object))

必须为真,以及其他一些限制。但是没有什么特定于数组。

我认为任何实现都不会 return 类型说明符在数组类型的维度中包含 *。他们很可能 return 一个完全省略维度的非常通用的类型说明符,或者一个包含给定数组的实际维度的非常具体的类型说明符。

没有什么能阻止实现 returning 类型说明符,就像您正在寻找的那样,但这将是非常不正常的。给定一个 3 维数组,为什么它会特别选择不指定最后一个维度而不是其他一个或所有维度?

I didn't feel like I learned much though beyond the pattern used in type notation.

您可能学到了一些东西:

  • Common Lisp 具有多维数组的类型声明,具有元素类型和指定维度和通配符维度。

  • 有这些类型的子类型和检查子类型关系的函数(SUBTYPEP)

  • 有简单数组(没有移位,没有填充指针,没有明确可调)和非简单数组

  • 你传给MAKE-ARRAY的元素类型不一定是创建数组的元素类型(见函数UPGRADED-ARRAY-ELEMENT-TYPE

*