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フォームをもつ無名関数をreturnします。
実際にはこのマクロはlambda
フォームを“自己クォート(self-quoting)”します。つまりCARがlambda
であるようなフォームは、そのフォーム自身を得ます。
(lambda (x) (* x x)) ⇒ (lambda (x) (* x x))
lambda
フォームは別に、1つの効果をもちます。このマクロは、function
(以下参照)をサブルーチンとして使用することにより、Emacs評価機能(Emacs
evaluator)とバイトコンパイラーに、その引数が関数であることを告げます。
このスペシャルフォームは、評価を行わずに、function-objectをreturnします。この点では、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
が関数としての使用を意図していることを知ることができないので、たとえこの関数が関数のように見えるとしても、このリストが関数であると決め込むことはできません。