common lisp cons从两个符号创建一个列表,clojure cons需要一个seq来cons到?
-
13-09-2020 - |
题
(免责声明-我知道Seqs在Clojure中的重要性)
在common lisp中,cons函数可用于将两个符号组合成一个列表:
(def s 'x)
(def l 'y)
(cons s l)
在clojure中-你只能对序列进行cons-cons没有被扩展到两个符号。所以你必须写:
(def s 'x)
(def l 'y)
(cons s '(l))
Clojure中是否有更高级别的模式来解释Common LISP和Clojure之间的这种区别?
解决方案
在Clojure中,与传统的Lisp不同,列表不是主要的数据结构。数据结构可以实现 ISeq 接口-这是它给出的数据结构的另一个视图-允许相同的函数访问每个元素。(列表已经实现了这一点。 seq?
检查某些东西是否实现 ISeq.(seq? '(1 2)), (seq? [1 2]))
Clojure只是有不同的行为(有充分的理由),当 cons
被使用,一个序列(它实际上是类型的 clojure.lang.Cons
)由 a
和 (seq b)
被归还。(a
是arg1和 b
(2)显然,符号没有也不能实现 ISeq.
Rich Hickey的序列截屏/谈话 但是,请注意 rest
已经改变了,它以前的行为现在在 next
, ,而那 lazy-cons
已被替换为 lazy-seq
和 cons
.
其他提示
您可以将任何东西放入COMBER的这两个插槽中。
FIN单元格用于构建列表。但是,人们可以创建具有CONS单元格的各种数据结构:树,图形,各种类型的专业列表,...
LISP的实施质量高度优化,可提供非常有效的CONS细胞。
Lisp列表只是使用cons单元格的常用方法(参见 雷纳的描述).Clojure最好被视为没有cons细胞(尽管类似的东西可能隐藏在引擎盖下)。的Clojure cons
是一个用词不当,它实际上应该只是命名 prepend
.
在Clojure中,使用双元素向量是首选: [:a :b]
.在引擎盖下,这样的小向量被实现为Java数组,并且非常简单和快速。
一只短手 (cons :a '(:b))
(或 (cons :a (cons :b nil))
)是 list
: (list :a :b)
.
当你说
> (cons 'a 'b)
在common lisp中,你不会得到一个列表,而是一个虚线对: (a . b)
, ,而结果
> (cons 'a (cons 'b nil))
是虚线对 (a . ( b . nil))
.
在第一个列表中 cdr()
这不是一个列表,因为它在这里 b
而不是 nil
, ,使其成为一个不当的列表。适当的名单必须由 nil
.因此,高阶函数如 mapcar()
朋友们不会工作,但我们保存了一个牢房。我猜Clojure的设计师删除了这个功能,因为它可能会导致混乱。