2013-10-01 93 views

回答

5

(list '+ '1 '2)產生符號列表+和數字12。評估將查找由符號+命名的函數和帶參數12調用它。

(list + '1 '2)產生由符號+命名的功能以及編號12的功能列表。評估它將調用已經直接作爲列表元素的函數,並使用來自列表其餘部分的參數。

從未有必要引用的數字,順便說一句。他們自我評估。

編輯

更有趣的情況下,你沒有在你的標題地址是在(eval '('+ 1 2))情況下會發生什麼?爲什麼會出現這種不返回3像其他情況下,所有最終調用由+的論據12命名的函數?

答案是,它是不同的,因爲這個時候,你所引述的符號+的兩倍。因此,符號不會被解析爲它所命名的函數,而是符號本身被稱爲函數。

現在什麼是當一個符號被作爲函數調用的行爲?它將其第一個參數視爲地圖,並將其視爲該地圖中的關鍵字。但是號碼1顯然不是地圖,所以現在通常會返回nil來指示找不到匹配的密鑰。

在這種情況下,雖然,有第二個參數來調用符號+,並且第二個參數被用作默認值時,沒有發現匹配鍵返回。所以這就是爲什麼表格(eval '('+ 1 2))返回2

編輯2

OK,現在終於回答這個問題:爲什麼引用列表產生不同的結果不是調用list功能具有相同的參數。這是因爲報價'停止它用在列表上的所有評價,但list功能與他們產生一個列表作爲元素之前評估其論點。

這些差異在打印各種形式,而不是直接發送到eval的一切都變得很清楚:

user> '(+ 1 2) 
(+ 1 2) 
user> '('+ 1 2) 
((quote +) 1 2) 
user> (list '+ '1 '2) 
(+ 1 2) 
user> (list + '1 '2) 
(#<core$_PLUS_ [email protected]> 1 2) 

你看,第一和第三種情況產生打印同樣的結果,因爲在這兩種這些案例你曾經引用過+。在第二種情況下,+是引用而不是兩次,並在最後它不是在所有的報價。

編輯3

最後一個除了應該有希望進一步澄清的事情:除非它的第一個元素名稱的宏或特殊的運算符,eval將遞歸評估列表中的所有元素(包括第一)前通過將其(被評估的)第一個參數作爲函數與列表的其餘部分作爲參數來評估列表本身。

如果第一個元素是'+(quote +)(這些都寫一樣的東西,所引用的符號+兩種不同的方式),將評估的符號+,並且將被稱爲功能。

如果第一個元素是+,那麼將評估爲實際加法函數(clojure.core$_PLUS_)。如果它已經是該功能,它將保持不變(除了列表和符號之外,基本上所有類型都是自我評估的)。在這兩種情況下,eval都會調用該函數。