関数を定義することは、全体の半分でしかありません。 関数を呼ぶまでは、つまり、実行を命じなければ、関数はなにもしません。 関数呼び出しは起動(invocation)ともいいます。
関数を起動するもっとも一般的な方法は、リストを評価することです。
たとえば、リスト(concat "a" "b")
を評価すると、
関数concat
を引数"a"
と"b"
で呼び出します。
評価についてはSee Evaluation。
読者のプログラムで式としてリストを書くときには、
呼び出す関数名を読者のプログラムに書きます。
つまり、プログラムを書くときに、
どの関数をどれだけの引数で呼び出すかを指定できることを意味します。
これが、普通にしたいことでしょう。
呼び出す関数を実行時に計算する必要がある場合もあるでしょう。
それには、関数funcall
を使います。
渡す引数の個数を実行時に決定する必要があるときには、
apply
を使います。
funcall
は、functionをargumentsで呼び出し、 functionがなにを返そうともそれを返す。
funcall
は関数なので、functionの呼び出しを評価するまえに functionを含めた引数すべてを評価する。 つまり、呼び出す関数を得るためのどんな式でも使えることを意味する。 また、funcall
は、読者がargumentsに書いた式を見ることはなく、 それらの値だけを見ることになる。 これらの値は、functionを呼び出す操作において、 2回目の評価を行うことはない。funcall
は、通常の関数呼び出し処理において、 引数を評価し終えたところから始める。引数functionは、Lisp関数か基本関数である必要がある。 スペシャルフォームやマクロは許されない。 それらには、『未評価』の引数式を与えたときだけ意味があるからである。
funcall
ではそのようにできない。 なぜなら、上の説明でわかるように、 未評価の引数をまったく知らないからである。(setq f 'list) ⇒ list (funcall f 'x 'y 'z) ⇒ (x y z) (funcall f 'x 'y '(z)) ⇒ (x y (z)) (funcall 'and t nil) error--> Invalid function: #<subr and>これらの例を
apply
の例と比較してほしい。
apply
は、funcall
のように、 functionをargumentsで呼び出すが、1点だけ異なる。 argumentsの最後はオブジェクトのリストであり、 functionにはこれを、単一のリストではなく、個々の引数として渡す。 これを、apply
は、 このリストの個々の要素が引数となるように分配するという。
apply
は、functionの呼び出し結果を返す。funcall
と同様に、functionはLisp関数か基本関数である必要がある。 スペシャルフォームやマクロは、apply
では意味がない。(setq f 'list) ⇒ list (apply f 'x 'y 'z) error--> Wrong type argument: listp, z (apply '+ 1 2 '(3 4)) ⇒ 10 (apply '+ '(1 2 3 4)) ⇒ 10 (apply 'append '((a b c) nil (x y z) nil)) ⇒ (a b c x y z)
apply
を使った興味深い例として、 Mapping Functionsのmapcar
の説明を見てほしい。
Lisp関数にとっては、引数として関数を受け取ったり、
データ構造(特に、フック変数や属性リスト)内の関数を探して
funcall
やapply
を使ってそれを呼び出すことは一般的です。
関数引数を受け付ける関数を
しばしばファンクショナル(functionals)と呼びます。
場合によっては、ファンクショナルを呼び出すときには、 引数としてなにもしない関数(no-op)を指定できると有用です。 つぎのものは、2種類のなにもしない関数です。