CLTL says the following: "In principle, an array in Common Lisp may have any number of dimensions, including zero. (A zero-dimensional array has exactly one element.)"
CLTL说明如下:“原则上,Common Lisp中的数组可以有任意多个维度,包括零。(零维度的数组只有一个元素。”
I'm talking about something like (make-array nil :initial-element 1)
我说的是类似于(make-arraynil:初始元素1)的内容
As far as i can see, these zero-dims arrays even have their own read syntax, like #0A1
, but they're not even considered to be sequences, so i can't coerce/concat/traverse them. The only thing i found out you can do, is to get/set its singleton element. So what's the purpose for having this not-exactly-an-array array kind? Why not just use arrays of length 1 (or just the value without any wrapper)?
就我所见,这些零维度数组甚至有自己的读取语法,就像#0A1,但它们甚至不被认为是序列,所以我不能强制/合并/遍历它们。我发现您可以做的唯一一件事就是获取/设置它的单例元素。那么,拥有这种不完全是数组的数组的目的是什么?为什么不使用长度为1的数组(或者只使用没有任何包装的值)?
更多回答
Why questions are so opinionated and hard to answer. Uniformity is almost certainly the justification that the creators had in mind. But it may be impossible to make you personally satisfied with someone else's justification, especially when phrased as "why not just use (some valid alternative)" -- that's a loaded question. You're right: you can use arrays of length 1. But some day you may find a piece of code that is easier to read if that one special case goes away by making it use a zero-dimensional array. Reducing cognitive load when reading code is a valid motivation.
为什么问题如此固执己见,很难回答。几乎可以肯定的是,一致性是创建者们心中的理由。但可能不可能让你个人对别人的理由感到满意,特别是当你被问及为什么不直接使用(一些有效的替代方案)时--这是一个沉重的问题。您是对的:您可以使用长度为1的数组。但有一天您可能会发现,如果通过使用零维数组来消除这一特殊情况,您可能会发现一段代码更易于阅读。减少阅读代码时的认知负荷是一种有效的动机。
"So what's the purpose for having this not-exactly-an-array array kind?" This may miss the point: a zero-dimensional array is an array type, and a naked value such as 1
is not an array type. "What are the use cases" may be too broad, but anytime you need an array type that can hold exactly one value a zero-dimensional array may be a good choice.
“那么,拥有这种不完全是数组的数组的目的是什么?”这可能没有抓住要点:零维数组是数组类型,而裸露的值(如1)不是数组类型。“用例是什么”可能过于宽泛,但无论何时您需要一个只能容纳一个值的数组类型,零维数组都可能是一个很好的选择。
This idea has precedence in mathematics: tensors can be represented as multi-dimensional arrays where zero-dimensional arrays represent scalars, one-dimensional arrays represent vectors, two-dimensional arrays represent matrices, and so on.
这个想法在数学上具有优先权:张量可以表示为多维数组,其中零维数组表示标量,一维数组表示向量,二维数组表示矩阵,依此类推。
Note that you can also have 0 in the dimension list:
请注意,维列表中也可以有0:
(make-array (list 0 10) :initial-element 3)
=> #2A()
This allows code that manipulates matrices in a generic way to avoid handling corner cases when one dimension is zero, I don't know of such cases myself but for example this question about Mathematica https://mathematica.stackexchange.com/questions/39522/zero-dimensional-matrices is talking about difficulties handling such corner cases.
这允许代码以通用的方式操作矩阵,以避免在一维为零时处理角例,我自己不知道这种情况,但例如,这个关于数学https://mathematica.stackexchange.com/questions/39522/zero-dimensional-matrices的问题谈论的是处理这种角例的困难。
I think its helpful in terms of robustness and uniformity if there is no constraint for arrays to be limited to non-zero dimensions, and that is probably why it is allowed.
我认为如果没有将数组限制为非零维的限制,在健壮性和一致性方面是有帮助的,这可能就是允许这样做的原因。
By itself a zero-dimensional array can be useful to implement a boxed-value, but you are right that there are other ways to implement that: a vector of size 1, a simple struct (defstruct box thing)
, etc. so another way to look at it is to find out which implementation costs less in terms of memory or access time, and maybe zero-dimensional arrays can be implemented more efficiently than arrays of size 1.
零维数组本身对于实现盒值很有用,但您说得对,还有其他实现方法:大小为1的向量、简单的结构(destruct box之类的东西)等等。因此,另一种看待它的方法是找出哪种实现在内存或访问时间方面成本更低,也许零维数组可以比大小为1的数组更有效地实现。
For example, using SBCL, (aref b)
does not need to check for the validity of the index in the array, whereas (aref b 0)
performs a check.
例如,使用SBCL,(AREF B)不需要检查数组中索引的有效性,而(AREF B 0)则执行检查。
(defun zero (b)
(declare (optimize (safety 1) (speed 3) (space 3) (debug 3)))
(declare (type (simple-array t nil) b))
(aref b))
; disassembly for ZERO
; Size: 24 bytes. Origin: #x54B8F453 ; ZERO
; 53: 498B4510 MOV RAX, [R13+16] ; thread.binding-stack-pointer
; 57: 488945F8 MOV [RBP-8], RAX
; 5B: 488B4209 MOV RAX, [RDX+9]
; 5F: 488B5001 MOV RDX, [RAX+1]
; 63: 488BE5 MOV RSP, RBP
; 66: F8 CLC
; 67: 5D POP RBP
; 68: C3 RET
; 69: CC10 INT3 16 ; Invalid argument count trap
(defun one (b)
(declare (optimize (safety 1) (speed 3) (space 3) (debug 3)))
(declare (type (simple-array t 1) b))
(aref b 0))
; disassembly for ONE
; Size: 34 bytes. Origin: #x54B009BD ; ONE
; BD: 498B4510 MOV RAX, [R13+16] ; thread.binding-stack-pointer
; C1: 488945F8 MOV [RBP-8], RAX
; C5: 48837AF900 CMP QWORD PTR [RDX-7], 0
; CA: 760C JBE L0
; CC: 488B5201 MOV RDX, [RDX+1]
; D0: 488BE5 MOV RSP, RBP
; D3: F8 CLC
; D4: 5D POP RBP
; D5: C3 RET
; D6: CC10 INT3 16 ; Invalid argument count trap
; D8: L0: CC24 INT3 36 ; INVALID-VECTOR-INDEX-ERROR
; DA: 08 BYTE #X08 ; RDX(d)
; DB: 82808010 BYTE #X82, #X80, #X80, #X10 ; 0
This is not definitive as this corner case could be improved over time, but in a way the zero-dimensional array expresses more clearly the constraint here.
这并不是决定性的,因为这个角的情况可能会随着时间的推移而改进,但在某种程度上,零维数组更清楚地表达了这里的约束。
Apart from the question of consistency, a zero-dimensional array is a box: it is a mutable object which holds a reference to exactly one other object.
撇开一致性问题不谈,零维数组是一个盒子:它是一个可变对象,它正好持有对另一个对象的引用。
Boxes are a useful enough notion that other languages have explicit types for them: for instance Racket has boxes.
Box是一个足够有用的概念,因为其他语言都有显式的类型:例如,racket就有Box。
In addition, a zero dimensional array can of course constrain the type of its element in the way that any array can, depending on what specialised array types exist in the implementation.
此外,零维数组当然可以像任何数组一样约束其元素的类型,这取决于实现中存在的特定数组类型。
Some implementations also have weak arrays, a zero-dimensional weak array is therefore a weak box, whose contents may be garbage-collected.
一些实现也具有弱数组,因此零维弱数组是弱盒,其内容可能被垃圾收集。
More than likely so you can have a 'vector' only DSL, like R does. In R everything, even single numbers, is an array/vector.
更有可能的是,这样你就可以像R一样拥有一个只有DSL的“矢量”。在R中,所有东西,即使是单个数字,都是一个数组/向量。
更多回答
Thanks, the tensors pov is convincing ). Maybe the use cases
phrasing is a bit incorrect. I rather mean 'how do you, as a lisper, use this feature)?'
谢谢,张量POV很有说服力)。也许用例的措辞有一点不正确。我的意思是‘作为一个口齿不清的人,你是如何使用这个功能的?’
thanks! this 'better performance' take is rather interesting. Note that you can also have 0 in the dimension list
, this one is what i easily understand.. the array with zero length in some axis, totally fits the general array idea. nil
axis in contrast seems to be inconsistent. Well the tensor
idea from the other answer generalizes it to be the sane idea for me ). Still, if you maybe know where can i read on the reason for this design, i'd really appreciate!
谢谢!这种“更好的表现”是相当有趣的。请注意,维度列表中也可以有0,这是我很容易理解的。在某一轴上长度为零的阵列完全符合一般的阵列思想。相比之下,零轴似乎是不一致的。好吧,另一个答案中的张量概念将其概括为对我来说是合理的想法)。不过,如果你知道我在哪里可以读到这个设计的原因,我会非常感激!
@leetwinski I'm sorry but I don't have any reference to point you at that would explain the decision behind this, maybe someone else will be able to, but searching around comp.lang.lisp doesn't give a lot of results (and probably the discussion was made elsewhere).
@leetwinski我很抱歉,但我没有任何参考资料可以解释这一决定背后的原因,也许其他人可以解释,但在Comp.lang.lisp上搜索并不能给出很多结果(而且可能是在其他地方进行了讨论)。
我是一名优秀的程序员,十分优秀!