1

我在不同版本的 Common Lisp 之间看到了不同的强制行为——想知道哪个是“正确的”,或者在这个看似简单的问题上标准模棱两可:

(coerce '(1 2 3) 'array) 

正确的口齿不清?它在 Clozure Common Lisp 中运行良好,但在 sbcl 中却不行。

当它不起作用时,将列表强制转换为数组的最简单方法是什么?

谢谢

4

2 回答 2

7

规范说:

如果结果类型是 的可识别子类型vector,并且对象是 a sequence,则结果是具有与objectvector相同元素的a 。

array不是的子类型vector——向量是一维数组,但array包括具有任意维数的数组。

您可以使用其中之一

(coerce '(1 2 3) 'vector)
(coerce '(1 2 3) '(array t (*)))

在第二个版本中,(*)指定未指定大小的单个维度。

您的用途未指定,因此实现可以随意实现它。如果它返回一个值,则该值必须是ARRAY某种类型的。

于 2019-08-12T21:45:17.673 回答
1

添加到 Barmar 的答案(这确实是一个评论,但它太长了),虽然 CCL 可以做它的工作,但我认为很明显,这样的事情很难在标准中定义。

考虑这样的事情:

(coerce '((1 2 3) (4 5 6) (7 8 9)) 'array)

这意味着什么结果?应该是:

  • 每个元素都是三元素列表的向量?
  • 相当于(make-array '(3 3) :initial-contents '((1 2 3) (4 5 6) (7 8 9)))
  • 该数组的转置?

我认为前两个中的任何一个都是合理的解释:有时你会想要一个,有时你会想要另一个。鉴于 CL 是一种行主要语言,第三个可能不合理。

因此,如果(coerce ... 'array)在标准中,您将如何指定您想要哪些?如果您只选择一个,应该是哪个(以及您现在如何与委员会中认为应该是另一个的人达成一致!)?

于 2019-08-13T10:28:15.760 回答