GNU Emacs 32.0.50 (9008bf64c3) のマニュアルを PLaMo 翻訳で機械翻訳したものです。誤訳を含むことがあります。原文: https://www.gnu.org/software/emacs/manual/html_node/elisp/Function-Indirection.html ・ emacs-doc.conao3.com

10.2.4 シンボル関数の間接参照

リストの先頭要素がシンボルである場合、評価ではそのシンボルの関数セルを調べ、元のシンボルの代わりにその内容を使用します。その内容が別のシンボルである場合、シンボル関数間接参照と呼ばれるこの処理は、シンボルではないものが得られるまで繰り返されます。シンボル関数間接参照の詳細については、関数の命名を参照してください。最終的にシンボルではないものが得られ、それは関数またはその他の適切なオブジェクトであるはずです。

より正確には、現在は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 を使用すると、シンボル関数の間接参照を明示的に簡単に実行できます。

関数: indirect-function 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))