通常、関数は defun で定義されると同時に名前も付与されますが、明示的なラムダ式――無名関数――を用いる方が便利な場合もあります。無名関数は、関数名が指定できるあらゆる場所で有効です。これらは変数の値として、あるいは関数の引数として指定されることがよくあります。例えば、mapcar の function
引数として無名関数を渡すと、その関数がリストの各要素に適用されます(マッピング関数 を参照)。これの具体的な例については、describe-symbols
の例 を参照してください。
匿名関数として使用するラムダ式を定義する際は、lambda マクロ、function 特殊形式、または #'
読み取り構文を使用してください:
このマクロは、引数リスト args、ドキュメント文字列 doc(あれば)、インタラクティブ仕様 interactive(あれば)、および body で指定されたボディフォームを持つ無名関数を返します。
例えば、このマクロを使うと lambda フォームはほぼ自己引用的になります。CAR が lambda
であるフォームを評価すると、ほぼそのフォーム自体のような値が返されます:
(lambda (x) (* x x))
⇒ #f(lambda (x) :dynbind (* x x))
レキシカルバインディングの下で評価すると、結果は同様のクロージャオブジェクトとなり、:dynbindマーカーがキャプチャされた変数に置き換えられます(クロージャを参照)。
lambda 形式にはもう一つ効果があります。function をサブルーチンとして使用することで(後述)、その引数が関数であることを Emacs
の評価器とバイトコンパイラに伝えるというものです。
この特殊な形式は、function-object の関数値を返します。多くの点で quote と似ています(クォート を参照)。しかし、quote
とは異なり、function-object
が関数として使用されることを意図しているという注記を、Emacs の評価器およびバイトコンパイラに伝える役割も果たします。function-object が有効なラムダ式であるとすると、これには2つの効果があります:
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
がこれを関数として使用する意図があることを知らないため、一見すると関数のように見えても、このリストが関数であるとは想定できません。