2010-09-07 57 views
6

Common Lisp中的一些實現,我們可以說,下面的表達式在clojure中,是(='a'a)是指'同一個原子'?

(eq 'a 'a) 

true因爲'a'a是「相同的原子」。

這可能是依賴於實現的,但它似乎短語(在一個受歡迎的LISP教材使用)假定爲相同的值的原子被存儲在存儲器中的相同位置。

在Java中,相同的值的2個實習字符串存儲在存儲器中的相同的位置。

現在的Clojure在JVM上繼承了Java的遺產,但它確實可以說,Clojure中(在JVM)兩個原子具有相同的值是相同的原子? (即如何做Clojure的原子存儲機制的工作?)

+2

Common Lisp的方言嗎?這些是什麼?什麼方言?通常的Common Lisp實現都實現ANSI Common Lisp。有CL的方言,但這並不重要,因爲大多數人(包括Lisp用戶)可能從來沒有聽說過他們。但Lisp有很多方言。 - 任何Common Lisp都會返回T(eq'a'a)。一個也不是一個原子,而是一個符號。術語「原子」在這方面也沒有意義。從歷史上看,所有不是缺陷的細胞都是原子。 – 2010-09-07 08:52:30

+0

「在Java中,具有相同值的兩個字符串存儲在內存中的相同位置。」 - 只有當他們都被禁止時。 – 2010-09-07 09:16:25

回答

21

首先,「原子」具有Clojure中有不同的含義比大多數其他的Lisp。見http://clojure.org/atoms

Clojure的=函數使用基於平等。因此,具有相同值的兩個對象即使存儲在內存中的不同位置,也將是=

爲了測試兩個對象實際上是相同的物體,在存儲器中的相同地址,可使用identical?功能。

4

我將解釋Common Lisp的一部分:

Common Lisp中(EQ '一' 一)始終返回T.

原因:在讀時間,讀者查找a,並且兩個a它將查找相同的符號a。由於任何符號是EQ本身,表達總是返回T.

這對於大多數類型的對象真實的,但也有一些例外。例如,數字和字符在Common Lisp中不是必需的EQ。其原因是效率。爲了比較這些數字是否相同或相同,可以使用函數EQL。

6

我認爲'a和'a將成爲不同的Java對象。我認爲,這證實了懷疑:

user> (def foo 5) 
#'user/foo 
user> (System/identityHashCode 'foo) 
578999228 
user> (System/identityHashCode 'foo) 
1724482638 

如果你看一下Clojure中的實際執行Symbol,你會看到一個符號由一個命名空間和名稱的那些字符串必須實習字符串。 Symbol.equals()方法依靠對這兩個字符串進行身份檢查,依靠字符串intern。

4

若要添加到亞歷克斯和斯圖爾特的答案,Clojure中的符號不​​能被作爲identical?,無論何時他們是=,主要是因爲它們可能攜帶元數據。兩個符號具有相同的.name.namespace組件,但不同的元數據將爲=,但不是identical?

事情可以令人信服地佈置成兩個符號具有相同的元數據,名稱空間和名稱將永遠是identical?,但這是(1)二沒有真正獲得太多的麻煩(因爲你仍舊有一些符號=但(2)與可能攜帶元數據的類型通常應該爲值相等(元數據不參與貢獻)進行比較的想法相反,而實際的指針相等應該保留用於特殊情況(主要涉及互操作)。

請注意,Clojure關鍵字是一個單獨的類型,其中=確實等同於identical?。 (很明顯,他們不能附加元數據。)

相關問題