2011-04-17 203 views
3

在CLISP如何分配存儲器塊,在CLISP

(eq (cons 'a 'b) (cons 'a 'b)) 

爲假(NIL)
因爲第一(AB)和第二(AB)分配在不同的存儲器中。

(eq 'a(car '(a b c))) 

爲真(T)

但是,爲什麼呢?
就像兩個(AB)一樣,首先是A和第二個A(car'(a b c))的結果是否必須使用不同的內存?如何在clisp中分配內存塊?

回答

4

每次調用CONS將創建一個新的cons單元。這些是不同的對象。

(eq (cons 1 2) (cons 1 2)) - > NIL

符號具有相同的名稱是相同的對象。

(eq 'foo 'foo) -> T

併發症

符號具有相同的名稱,但在不同的是不同的對象。

(eq 'bar::foo 'baz::foo) -> NIL

符號使用相同的名稱,沒有包可能是同一對象或沒有。

(eq '#:foo '#:foo) -> NIL

(let ((sym '#:foo)) 
    (eq sym sym)) 
-> T 
+0

其實,這是不正確的。 #:前綴保證符號不被攔截,因此它們保證不是eq。 – 2011-04-17 14:41:39

+0

@EliasMårtenson:這是正確的,但符號可以存儲在變量中,如果你比較相同的符號,即使它沒有被幹擾,那麼你總是得到T.這個基於身份的「同一性」例如沒有爲數字定義,字符。 – 2011-04-17 15:49:45

1

CONS創建配對。在您的具體示例中,兩對都包含符號A和B.

通常,您不必擔心在Common Lisp中分配內存塊,而是會創建結構(數組,列表,類,哈希表)。唯一分配內存塊的時候,就是爲了調用另一種語言鏈接的函數。

3

這是因爲'a被拘留。也就是說,無論何時在代碼中輸入「a」(在第二個示例中,它會出現兩次),它們將解析爲相同的符號。這是因爲讀者將使用INTERN函數獲得對該符號的引用。 (Hyperspec docs)。

這就是爲什麼(eq 'a 'a)返回T。這有一個例外。帶#前綴的符號永遠不會被執行。 GENSYM使用此功能可確保在編寫宏時獲得唯一的符號。

1

符號是特殊對象。當Common Lisp首次遇到一個符號時,它將被實現,即創建一個代表該符號的對象並將該符號映射到該對象。對於該符號的所有進一步參考,使用符號名稱作爲關鍵字來檢索該對象。例如,假設Common Lisp在符號爲a的內存位置0x05處創建了一個對象。對a的所有進一步參考將指向相同的對象。這意味着(eq 'a 'a)基本上變成(eq 0x05 0x05),其評估爲T

cons的情況有所不同。每次調用cons都會在內存中創建一個新對象。撥打cons的第一個電話將在位置0x10處創建一個對象,並在0x20處創建第二個電話。所以你的第一個比較變成(eq 0x10 0x20),它返回nil。對的組件可能指向相同的對象,但對本身指向不同的位置。