リストの先頭要素がシンボルである場合、評価ではそのシンボルの関数セルを調べ、元のシンボルの代わりにその内容を使用します。その内容が別のシンボルである場合、シンボル関数間接参照と呼ばれるこの処理は、シンボルではないものが得られるまで繰り返されます。シンボル関数間接参照の詳細については、関数の命名を参照してください。最終的にシンボルではないものが得られ、それは関数またはその他の適切なオブジェクトであるはずです。
より正確には、現在はLisp関数(ラムダ式)、バイトコード関数、プリミティブ関数、Lispマクロ、特殊フォーム、またはオートロードオブジェクトのいずれかであるはずです。これらの型はそれぞれ、以下のセクションのいずれかで説明されています。オブジェクトがこれらの型のいずれでもない場合、Emacsはinvalid-functionエラーを発生させます。
以下の例では、シンボル間接参照の処理について説明します。シンボルの関数セルを設定するには fset
を、関数セルの内容を取得するには symbol-function を使用します(関数セルの内容へのアクセス を参照)。具体的には、シンボル
car を first の関数セルに、シンボル
first を erste
の関数セルに格納します。
;; Build this function cell linkage:
;; ------------- ----- ------- -------
;; | #<subr car> | <-- | car | <-- | first | <-- | erste |
;; ------------- ----- ------- -------
(symbol-function 'car)
⇒ #<subr car>
(fset 'first 'car)
⇒ car
(fset 'erste 'first)
⇒ first
(erste '(1 2 3)) ; Call the function referenced by erste.
⇒ 1
これに対し、以下の例では、最初の要素がシンボルではなく匿名のLisp関数であるため、シンボル関数の間接参照を介さずに関数を呼び出しています。
((lambda (arg) (erste arg))
'(1 2 3))
⇒ 1
関数自体を実行するとその本体が評価されますが、この際、ersteを呼び出すときにシンボル関数の間接参照が行われます。
この形式はほとんど使われず、現在は非推奨となっています。代わりに、次のように記述してください:
(funcall (lambda (arg) (erste arg))
'(1 2 3))
あるいは単に
(let ((arg '(1 2 3))) (erste arg))
組み込み関数 indirect-function
を使用すると、シンボル関数の間接参照を明示的に簡単に実行できます。
この関数は、function の意味を関数として返します。function がシンボルである場合、function の関数定義を探し、その値から処理を再開します。function がシンボルでない場合は、function 自体を返します。
この関数は、最後のシンボルが未束縛である場合に nil を返します。
また、現在は廃止されており効果のない、2つ目のオプション引数もあります。
Lispでindirect-functionを定義する方法は以下の通りです。
(defun indirect-function (function)
(if (and function
(symbolp function))
(indirect-function (symbol-function function))
function))