(免责声明 - 我知道Seqs在Clojure中的重要性)
在常见的lisp中,cons函数可用于将两个符号组合成一个列表:
(def s 'x)
(def l 'y)
(cons s l)
在clojure中 - 你只能使用一个序列 - 缺点还没有扩展到使用两个符号。所以你必须写:
(def s 'x)
(def l 'y)
(cons s '(l))
Clojure中有更高级别的模式可以解释Common LISP和Clojure之间的区别吗?
答案 0 :(得分:9)
在Clojure中,与传统的Lisp不同,列表不是主要的数据结构。数据结构可以实现ISeq接口 - 这是它给出的数据结构的另一个视图 - 允许相同的函数访问每个接口中的元素。 (列表已经实现了这一点。seq?
检查某些内容是否实现ISeq。(seq? '(1 2)), (seq? [1 2]))
Clojure只是采取不同的行为(有充分理由),因为当使用cons
时,序列(它实际上是由clojure.lang.Cons
和a
构成的类型(seq b)
}。(a
是arg 1和b
arg 2)显然,符号不会并且无法实施ISeq。
Sequences screencast/talk by Rich Hickey但是,请注意rest
已更改,之前的行为现在位于next
,lazy-cons
已替换为lazy-seq
, cons
。
答案 1 :(得分:6)
在Common Lisp中,CONS创建了一个所谓的CONS单元,类似于带有两个插槽的记录:'car'和'cdr'。
你可以将ANYTHING放入cons小区的两个插槽中。
Cons单元格用于构建列表。但是可以用cons单元创建各种数据结构:树,图,各种类型的专用列表......
Lisp的实现经过高度优化,可以提供非常有效的cons单元。
答案 2 :(得分:3)
Lisp列表只是使用cons单元格的常用方法(参见Rainer's description)。最好看到Clojure没有cons细胞(虽然类似的东西可能隐藏在引擎盖下)。 Clojure cons
是用词不当,实际上应该只是命名为prepend
。
答案 3 :(得分:3)
在Clojure中,首选使用双元素向量:[:a :b]
。在引擎盖下,这些小向量被实现为Java数组,并且非常简单和快速。
(cons :a '(:b))
(或(cons :a (cons :b nil))
)的简写为list
:(list :a :b)
。
答案 4 :(得分:2)
当你说
时> (cons 'a 'b)
在常见的lisp中你不会得到一个列表而是一个虚线对:(a . b)
,而
> (cons 'a (cons 'b nil))
是虚线对(a . ( b . nil))
。
在第一个列表中,cdr()
不是列表,因为它在b
而不是nil
,因此它是一个不正确的列表。必须由nil
终止正确的列表。因此,像mapcar()
和朋友这样的高阶函数将不起作用,但我们保存了一个缺点。我猜Clojure的设计师因为它可能引起的混乱而删除了这个功能。