Next: Function Cells, Previous: Mapping Functions, Up: Functions [Contents][Index]
関数は通常はdefun
により定義されて、同時に名前が与えられますが、明示的にラムダ式を使う — 無名関数(anonymous
function)のほうが便利なときもあります。無名関数は名前つき関数が有効な場所ならどこでも有効です。無名関数は変数や関数の引数に割り当てられることがよくあります。たとえばある関数をリストの各要素に適用するmapcar
のfunction引数に渡すかもしれません(Mapping Functionsを参照)。現実的な例はdescribe-symbols exampleを参照してください。
無名関数として使用するためのラムダ式を定義するとき、原則的にはリストを構築する任意の手法を使用できます。しかし通常はマクロlambda
、スペシャルフォームfunction
、または入力構文#'
を使用するべきです。
このマクロは引数リストargs、(もしあれば)ドキュメント文字列doc、(もしあれば)インタラクティブ指定interactive、およびbodyで与えられるbodyフォームをもつ無名関数をリターンする。
実際にはこのマクロはlambda
フォームを“自己クォート(self-quoting)”します。つまりCARがlambda
であるようなフォームは、そのフォーム自身を得ます。
(lambda (x) (* x x)) ⇒ (lambda (x) (* x x))
lambda
フォームは別の1つの効果をもつ。このマクロはfunction
(以下参照)をサブルーチンとして使用することにより、Emacs評価機能(Emacs
evaluator)とバイトコンパイラーに、その引数が関数であることを告げる。
このスペシャルフォームは評価を行わずにfunction-objectをリターンする。この点ではquote
(Quotingを参照)と似ている。しかしquote
とは異なり、Emacs評価機能とバイトコンパイラーに、これを関数として使用する意図を告げる役割をもつ。function-objectが有効なラムダ式と仮定すると、これは2つの効果をもつ:
入力構文#'
はfunction
の使用の略記です。以下のフォームは等価です:
(lambda (x) (* x x)) (function (lambda (x) (* x x))) #'(lambda (x) (* x x))
以下の例では3つ目の引数に関数をとるchange-property
関数を定義して、その後のchange-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
が関数としての使用を意図していることを知ることができないので、たとえこの関数が関数のように見えるとしても、このリストが関数であると決め込むことができません。