2010-07-11 51 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)