Next: 関数フォームの評価, Previous: リストフォームの分類, Up: フォームの種類 [Contents][Index]
If the first element of the list is a symbol then evaluation examines the symbol’s function cell, and uses its contents instead of the original symbol. If the contents are another symbol, this process, called symbol function indirection, is repeated until it obtains a non-symbol. See 関数の命名, for more information about symbol function indirection. We eventually obtain a non-symbol, which ought to be a function or other suitable object.
適切なオブジェクトとは、より正確にはLisp関数(ラムダ式)、バイトコード関数、プリミティブ関数、Lispマクロ、スペシャルフォーム、またはオートロードオブジェクトです。これらそれぞれの型については以降のセクションで説明します。これらの型以外のオブジェクトならEmacsはinvalid-function
エラーをシグナルします。
以下の例はシンボルインダイレクションのプロセスを説明するものです。わたしたちはシンボルの関数セルへの関数のセットにfset
、関数セルの内容(関数セルの内容へのアクセスを参照)の取得にsymbol-function
を使用します。具体的にはfirst
の関数セルにシンボルcar
を格納して、シンボルfirst
をerste
の関数セルに格納します。
;; この関数セルのリンクを構築する:
;; ------------- ----- ------- -------
;; | #<subr car> | <-- | car | <-- | first | <-- | erste |
;; ------------- ----- ------- -------
(symbol-function 'car) ⇒ #<subr car>
(fset 'first 'car) ⇒ car
(fset 'erste 'first) ⇒ first
(erste '(1 2 3)) ; erste
により参照される関数を呼び出す
⇒ 1
対照的に、以下の例ではシンボル関数インダイレクションを使用せずに関数を呼び出しています。なぜなら1番目の要素はシンボルではなく、無名Lisp関数(anonymous Lisp function)だからです。
((lambda (arg) (erste arg)) '(1 2 3)) ⇒ 1
関数自身を実行するとその関数のbodyを評価します。ここではerste
を呼び出すとき、シンボル関数インダイレクションが行なわれています。
このフォームが使用されるのは稀であり、現在では推奨されていません。かわりに以下のように記述するべきです:
(funcall (lambda (arg) (erste arg)) '(1 2 3))
または単に
(let ((arg '(1 2 3))) (erste arg))
ビルトイン関数のindirect-function
は、明示的にシンボル関数インダイレクションを処理するための簡単な方法を提供します。
この関数はfunctionが意味するものを関数としてリターンする。functionがシンボルならfunctionの関数定義を探して、その値で最初からやり直す。functionがシンボルでなければfunction自身をリターンする。
This function returns nil
if the final symbol is unbound.
There is also a second, optional argument that is obsolete and has no effect.
以下はLispでindirect-function
を定義する例である:
(defun indirect-function (function) (if (and function (symbolp function)) (indirect-function (symbol-function function)) function))