Next: , Previous: , Up: Functions   [Contents][Index]


12.7 Anonymous Functions

関数は通常、defunにより定義され、同時に名前が与えられますが、明示的にラムダ式を使う — 無名関数(anonymous function)のほうが便利なときもあります。無名関数は、名前つき関数が有効な場所なら、どこでも有効です。無名関数は変数や関数の引数に割り当てられることがよくあります。たとえば、ある関数をリストの各要素に適用するmapcarfunction引数に渡すかもしれません(Mapping Functionsを参照してください)。現実的な例は、describe-symbols exampleを参照してください。

無名関数として使用するためのラムダ式を定義するとき、原則的にはリストを構築する任意の手法を使用できます。しかし通常は、マクロlambda、スペシャルフォームfunction、または入力構文#'を使用するべきです。

Macro: lambda args [doc] [interactive] body…

このマクロは引数リストargs、(もしあれば)ドキュメント文字列doc、(もしあれば)インタラクティブ指定interactive、およびbodyで与えられるbodyフォームをもつ無名関数をreturnします。

実際にはこのマクロはlambdaフォームを“自己クォート(self-quoting)”します。つまりCARlambdaであるようなフォームは、そのフォーム自身を得ます。

(lambda (x) (* x x))
     ⇒ (lambda (x) (* x x))

lambdaフォームは別に、1つの効果をもちます。このマクロは、function(以下参照)をサブルーチンとして使用することにより、Emacs評価機能(Emacs evaluator)とバイトコンパイラーに、その引数が関数であることを告げます。

Special Form: function function-object

このスペシャルフォームは、評価を行わずに、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が関数としての使用を意図していることを知ることができないので、たとえこの関数が関数のように見えるとしても、このリストが関数であると決め込むことはできません。