最初のものは機能しません。しかし、2つ目は機能するため、混乱します。誰かがそれについて少し説明できますか?
CL-USER> (funcall (first '(#'+ +)) 1)
; Evaluation aborted on #<TYPE-ERROR expected-type:
; (OR FUNCTION SYMBOL) datum: #'+>.
CL-USER> (funcall #'+ 1)
1
最初のものは機能しません。しかし、2つ目は機能するため、混乱します。誰かがそれについて少し説明できますか?
CL-USER> (funcall (first '(#'+ +)) 1)
; Evaluation aborted on #<TYPE-ERROR expected-type:
; (OR FUNCTION SYMBOL) datum: #'+>.
CL-USER> (funcall #'+ 1)
1
は#'
リーダーマクロです。#'+
の略語です(function +)
。'
に展開するリーダーマクロ(quote …)
です。後者は、その引数を未評価で返します。したがって、'(#'+ +)
yields ((function +) +)
(読み取り時#'+
に変換されます)。(function +)
これfirst
は単なるリスト(function +)
であり、関数ではありません。これで、(function +)
がとして出力され#'+
ます。これは、デバッガーに表示されるものです。
非リテラルリストを使用すると機能します。
CL-USER> (funcall (first (list #'+ '+)) 1)
1
入力は次のとおりです。
(funcall (first '(#'+ +)) 1)
'(#'+ +)
私たちがそれを評価するときは何ですか?前の引用符はフォームの評価を妨げるため、結果は読者がデータとして読み取ったものになります。
これは2つの項目のリストです。
(function +)
+
通常、((function +)+)と記述されます。
元の入力の引用は、リストまたはその内容を評価したくないと明示的に述べていることに注意してください。
今、あなたはFIRST
このリストを呼びます。結果は最初の項目です:(function +)
。これは2つのアイテムのリストです:
function
+
ここで、このリストと値1を使用してFUNCALLを呼び出します。
FUNCALLは、入力として関数またはシンボルを想定しています。あなたはそれに(function +)
最初の引数としてリストを与えます。FUNCALLはそれをどうするかわかりません。
どうすれば修理できますか?おそらく、を評価した結果である関数を使用したいと思うでしょう(function +)
。
したがって、元のリストを書き直す必要があります。`'(#' + +))'の代わりに、たとえば次を使用します。
(list #'+ '+)
また
`(,#'+ +) ; note the backquote in front