第一個不起作用。 但第二個作品,這讓我感到困惑。 任何人都可以解釋一下嗎?爲什麼我不能使用從Common Lisp列表中提取的函數符號(#')?
CL-USER> (funcall (first '(#'+ +)) 1)
; Evaluation aborted on #<TYPE-ERROR expected-type:
; (OR FUNCTION SYMBOL) datum: #'+>.
CL-USER> (funcall #'+ 1)
1
第一個不起作用。 但第二個作品,這讓我感到困惑。 任何人都可以解釋一下嗎?爲什麼我不能使用從Common Lisp列表中提取的函數符號(#')?
CL-USER> (funcall (first '(#'+ +)) 1)
; Evaluation aborted on #<TYPE-ERROR expected-type:
; (OR FUNCTION SYMBOL) datum: #'+>.
CL-USER> (funcall #'+ 1)
1
#'
是一個閱讀器宏。 #'+
是(function +)
的縮寫。 '
是一個擴大到(quote …)
的讀者宏。後者返回未評估的論點。因此,'(#'+ +)
收益率((function +) +)
(#'+
將在讀取時變成(function +)
)。這是first
只是列表(function +)
,這不是一個函數。現在,(function +)
被打印爲#'+
,這是您在調試器中看到的內容。
使用非文字列表將工作:
CL-USER> (funcall (first (list #'+ '+)) 1)
1
你輸入的是:
(funcall (first '(#'+ +)) 1)
什麼是'(#'+ +)
當我們評價它?在前面的報價阻止形式的評價,所以結果正是讀者已經讀出的數據:
這是兩個項目的列表:
(function +)
+
通常寫爲((function +)+)。
請注意,原始輸入中的引號明確表示您不想評估列表或其內容。
現在您在此列表上撥打FIRST
。結果是第一項:(function +)
。這是兩個項目的列表:
function
+
現在你罵FUNCALL與此列表和1
FUNCALL需要一個函數或符號作爲價值輸入。您將它列爲第一個參數(function +)
。 FUNCALL不知道如何處理它。
我們該如何修復?您可能想要使用評估(function +)
的結果功能。
所以你需要重寫你的原始列表。代替` '(#' + +))」使用例如:
(list #'+ '+)
或
`(,#'+ +) ; note the backquote in front
由於danlei。正如你所說,'(第一'(#'+ +))'的結果是'(函數+)',對嗎?但爲什麼它不被自動評估爲'#'+'? '#'+'和'(function +)'有什麼不同?他們都不是**功能對象**嗎? –
問題在於:爲什麼不評估函數? (請記住'#''只是一個閱讀器宏,沒有任何東西會被評估到#'+「中)。 ''(#'+ +)'將被讀作'(quote((函數+)+)',這會在讀取時發生,也就是讀取器宏的擴展現在,由於'(function +)'在裏面的引用表達式,它只會返回未評估的值,因爲這就是'quote'的作用。 – danlei
在讀取之後,'#'+'和'(function +)'之間沒有區別''#'+'是隻是一個擴展爲'(function +)'的縮寫,但這只是一個列表 - * code *,但仍然是一個列表。因此,'(function +)'不是一個函數對象,但會產生一個函數對象* *(*)不會評估它的參數,這就是爲什麼'(function +)'保持原狀:一個列表(恰好是代碼,當它被評估時,返回一個函數對象) – danlei