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

13.7 無名関数

通常、関数は defun で定義されると同時に名前も付与されますが、明示的なラムダ式――無名関数――を用いる方が便利な場合もあります。無名関数は、関数名が指定できるあらゆる場所で有効です。これらは変数の値として、あるいは関数の引数として指定されることがよくあります。例えば、mapcar の function 引数として無名関数を渡すと、その関数がリストの各要素に適用されます(マッピング関数 を参照)。これの具体的な例については、describe-symbols の例 を参照してください。

匿名関数として使用するラムダ式を定義する際は、lambda マクロ、function 特殊形式、または #' 読み取り構文を使用してください:

マクロ: lambda args [doc] [interactive] body…

このマクロは、引数リスト args、ドキュメント文字列 doc(あれば)、インタラクティブ仕様 interactive(あれば)、および body で指定されたボディフォームを持つ無名関数を返します。

例えば、このマクロを使うと lambda フォームはほぼ自己引用的になります。CAR が lambda であるフォームを評価すると、ほぼそのフォーム自体のような値が返されます:

(lambda (x) (* x x))
     ⇒ #f(lambda (x) :dynbind (* x x))

レキシカルバインディングの下で評価すると、結果は同様のクロージャオブジェクトとなり、:dynbindマーカーがキャプチャされた変数に置き換えられます(クロージャを参照)。

lambda 形式にはもう一つ効果があります。function をサブルーチンとして使用することで(後述)、その引数が関数であることを Emacs の評価器とバイトコンパイラに伝えるというものです。

特殊形式: 関数 function-object

この特殊な形式は、function-object の関数値を返します。多くの点で quote と似ています(クォート を参照)。しかし、quote とは異なり、function-object が関数として使用されることを意図しているという注記を、Emacs の評価器およびバイトコンパイラに伝える役割も果たします。function-object が有効なラムダ式であるとすると、これには2つの効果があります:

  • コードがバイトコンパイルされると、function-object はバイトコード関数オブジェクトにコンパイルされます(バイトコンパイルを参照)。
  • 語彙的束縛が有効な場合、function-object はクロージャに変換されます。クロージャを参照してください。

function-object がシンボルであり、コードがバイトコンパイルされる場合、その関数が定義されていないか、あるいは実行時に認識されない可能性があると、バイトコンパイラが警告を出します。

読み取り構文 #' は、function を使用する際の短縮表記です。以下の形式はいずれも等価です:

(lambda (x) (* x x))
(function (lambda (x) (* x x)))
#'(lambda (x) (* x x))

以下の例では、第3引数に関数を受け取る change-property 関数を定義し、続いて、匿名関数を渡すことで change-property を利用する double-property 関数を定義します:

(defun change-property (symbol prop function)
  (let ((value (get symbol prop)))
    (put symbol prop (funcall function value))))

(defun double-property (symbol prop)
  (change-property symbol prop (lambda (x) (* 2 x))))

なお、lambda形式は記載していません。

上記のコードをコンパイルすると、無名関数もコンパイルされます。例えば、無名関数をリストとしてクォートして構築した場合には、このようなことは起こりません:

(defun double-property (symbol prop)
  (change-property symbol prop '(lambda (x) (* 2 x))))

その場合、匿名関数はコンパイル済みコード内でラムダ式として保持されます。バイトコンパイラは、change-property がこれを関数として使用する意図があることを知らないため、一見すると関数のように見えても、このリストが関数であるとは想定できません。