常见的lisp cons从两个符号创建一个列表,clojure cons需要一个seq来构建?

时间:2010-07-11 10:58:43

标签: clojure lisp common-lisp sequence cons

(免责声明 - 我知道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之间的区别吗?

5 个答案:

答案 0 :(得分:9)

在Clojure中,与传统的Lisp不同,列表不是主要的数据结构。数据结构可以实现ISeq接口 - 这是它给出的数据结构的另一个视图 - 允许相同的函数访问每个接口中的元素。 (列表已经实现了这一点。seq?检查某些内容是否实现ISeq(seq? '(1 2)), (seq? [1 2])) Clojure只是采取不同的行为(有充分理由),因为当使用cons时,序列(它实际上是由clojure.lang.Consa构成的类型(seq b)}。(a是arg 1和b arg 2)显然,符号不会并且无法实施ISeq

Clojure.org/sequences

Sequences screencast/talk by Rich Hickey但是,请注意rest已更改,之前的行为现在位于nextlazy-cons已替换为lazy-seqcons

clojure.lang.RT

答案 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的设计师因为它可能引起的混乱而删除了这个功能。