Clojure

與其他 Lisp 的差異

此資訊提供給熟悉 Common Lisp 或 Scheme 的程式設計師。

  • Clojure 區分大小寫

  • Clojure 是 Lisp-1

  • () 與 nil 不同

  • 讀取器沒有副作用

  • 關鍵字不是符號

  • 符號不是儲存位置(請參閱 Var)

  • nil 不是符號

  • t 不是語法,請使用 true

  • 讀取表格無法由使用者程式存取

  • let 順序繫結

  • do 不是迴圈建構

  • 沒有尾呼叫最佳化,請使用 recur

  • 語法引號會執行符號解析,所以 `x'x 不同。

  • ` 有自動產生符號。

  • ~ 是取消引號,, 是空白

  • 有讀取語法可處理映射、向量和集合

  • consfirstrest 會操作序列抽象,而不是具體的 cons 單元格

  • 大多數資料結構都是不可變的

  • lambda 是 fn,並支援依據元數進行重載

  • = 是等號謂詞

  • 全域變數可以在不影響詞彙本地繫結的情況下動態重新繫結(如果宣告為動態)。無需特殊宣告即可區分動態繫結和詞彙繫結。由於 Clojure 是 Lisp-1,因此可以動態重新繫結(全域)函式(如果將其標記為動態)。

  • 沒有 letreclabelsflet - 使用 (fn name [args]…​) 進行自我參考,letfn 進行相互參考。

  • 在 Clojure 中,nil 表示「沒有」。它表示任何類型的值不存在,不特定於清單或序列。

  • 空集合與 nil 不同。Clojure 沒有將 nil'() 等同。

  • false 表示兩個可能的布林值之一,另一個是 true

  • 集合不只有清單。您可以有空集合的實例,其中一些有文字支援([]{}())。因此,沒有哨兵空集合值。

  • 從 Scheme 來說,nil 可能最接近您對 #f 的概念。

  • Clojure 的一大區別在於序列。序列不是特定集合,特別是它們不一定是具體清單。當您詢問空集合的元素序列(透過呼叫 seq)時,它會傳回 nil,表示「我無法產生一個」。當您詢問序列最後一個元素的 rest 時,它會傳回另一個邏輯序列。您只能透過依序呼叫 seq 來判斷該序列是否為空。這使序列和序列協定能夠延遲

  • 有些序列函式對應到 Scheme 和 CL 中的函式,這些函式只操作配對/cons(「清單」)並傳回表示「空」清單的哨兵值('()nil)。Clojure 傳回值不同,不會傳回特定空集合,而是傳回另一個邏輯序列。有些序列函式在 Scheme/CL 中沒有對應函式,並對應到類似 Haskell/ML 的函式。有些函式會傳回無限或計算序列,其中類比到具體資料結構(例如 Scheme/CL 清單)充其量只是勉強成立。

  • 區分集合/資料結構和序列/反覆運算很有幫助。在 CL 和 Scheme 中,它們是混淆的,在 Clojure 中,它們是分開的。

Clojure Common Lisp Scheme Java

有 nil 嗎?

nil - 表示「無」

nil - 表示 false 或空清單

-

null

有 true 嗎?

true

-

#t

true (原始)

有 false 嗎?

false

-

#f

false (原始)

條件式區分

nil 或 false/其他所有

nil/非 nil

#f/非 #f

false/true

清單/序列函式庫會操作區分的具體類型嗎?

否 - seq 抽象具有許多集合實作

是 - cons 和向量

是 - 配對

否 - Iterator 抽象具有許多集合實作

單一空清單值?

否 - 可以有具體集合類型的不同空值

nil

'()

序列結束回傳

一個邏輯序列,其中 seq 回傳 nil

nil

'()

false

主機 null

nil

NA

NA

NA

主機 true

true (boxed)

NA

NA

NA

主機 false

false (boxed)

NA

NA

NA