2010-07-11 19 views
13

(免责声明 - 我所知道的Seqs的Clojure中的意义)common lisp cons从两个符号创建一个列表,clojure缺点需要一个seq来提供?

Common Lisp中的利弊功能可用于两个符号组合成一个列表:

(def s 'x) 
(def l 'y) 
(cons s l) 

Clojure中 - 你可以只对一个序列负责 - cons没有扩展到使用两个符号。所以,你必须写:

(def s 'x) 
(def l 'y) 
(cons s '(l)) 

有Clojure中的一个更高层次的图案,说明Common Lisp的Clojure的和之间的差异?

+0

我一直在Clojure编程一点,甚至没有意识到这一点!如果你声称是正确的,这是一个很好的问题:) – 2010-07-11 11:04:00

+0

请注意,使用'conj'通常比'cons'更好。有关更多详细信息,请参阅我对此问题的回答(以及由cgrand发表的评论):http://stackoverflow.com/questions/3008411/clojure-seq-cons-vs-list-conj(实际上,该答案也解释了在Clojure中'cons'的功能与传统的Lisp'cons'在一定程度上相反。) – 2010-07-11 12:01:54

+3

您的第一个示例不是列表,它是一对。一对(a。b)与两个元素(ab)的列表不同,它恰好是这一对(a。(b。nil)) – Zorf 2010-07-12 05:26:45

回答

9

在Clojure中,与传统的Lisps不同,列表不是主要的数据结构。数据结构可以实现ISeq接口 - 这是它给出的数据结构的另一个视图 - 允许相同的函数访问每个元素。事情是否实现ISeq(名单已经实现了这一点。seq?检查。(seq? '(1 2)), (seq? [1 2])) Clojure中只是充当不同(有很好的理由),因为当cons时,一个序列(它实际上的a(seq b)返回构造clojure.lang.Cons型)。(a是ARG 1和b ARG 2)显然,符号不和无法实现ISeq

Clojure.org/sequences

Sequences screencast/talk by Rich Hickey但是请注意,rest已经变了,这是以前的行为是现在next,而lazy-cons已被lazy-seqcons所取代。

clojure.lang.RT

2

当你说

> (cons 'a 'b) 
Common Lisp中

你没有得到一个列表,但一个点对:(a . b),而中

> (cons 'a (cons 'b nil)) 

结果是点对(a . (b . nil))

在第一个列表中,cdr()不是一个列表,因为它在这里是b而不是nil,因此它是不正确的列表。正确的列表必须以nil终止。因此mapcar()和朋友等高阶函数将无法工作,但我们可以节省一个精细单元。我猜Clojure的设计师可能会导致混淆,因此删除了这个功能。

+1

应该注意的是'(a。(b。nil)) '_is_一个Lisp列表,通常记为'(ab)'。 – Svante 2010-07-11 12:27:35

5

在Common Lisp的缺点创建一个所谓的缺点细胞,这是类似于两个插槽的记载:“汽车”和“CDR”。

你可以把任何东西放到cons cell的两个插槽中。

Cons单元格用于构建列表。但是我们可以用cons单元创建各种数据结构:树,图形,各种专用列表......

Lisp的实现经过高度优化以提供非常有效的反馈单元。

3

Lisp列表只是使用cons单元格的常用方法(请参阅Rainer's description)。 Clojure最好被视为没有缺陷细胞(尽管类似的东西可能隐藏在引擎盖下)。 Clojure cons是一个用词不当,它实际上应该被命名为prepend

3

在Clojure中,首选使用两元素向量:[:a :b]。在这种情况下,这些小向量被实现为Java数组,并且非常简单和快速。

(cons :a '(:b))(或(cons :a (cons :b nil)))的简写为list(list :a :b)

相关问题