Next: , Previous: Defining Functions, Up: Functions


11.5 関数呼び出し

関数を定義することは、全体の半分でしかありません。 関数を呼ぶまでは、つまり、実行を命じなければ、関数はなにもしません。 関数呼び出しは起動(invocation)ともいいます。

関数を起動するもっとも一般的な方法は、リストを評価することです。 たとえば、リスト(concat "a" "b")を評価すると、 関数concatを引数"a""b"で呼び出します。 評価についてはSee Evaluation

読者のプログラムで式としてリストを書くときには、 呼び出す関数名を読者のプログラムに書きます。 つまり、プログラムを書くときに、 どの関数をどれだけの引数で呼び出すかを指定できることを意味します。 これが、普通にしたいことでしょう。 呼び出す関数を実行時に計算する必要がある場合もあるでしょう。 それには、関数funcallを使います。 渡す引数の個数を実行時に決定する必要があるときには、 applyを使います。

— Function: funcall function &rest arguments

funcallは、functionargumentsで呼び出し、 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の例と比較してほしい。

— Function: apply function &rest arguments

applyは、funcallのように、 functionargumentsで呼び出すが、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 Functionsmapcarの説明を見てほしい。

Lisp関数にとっては、引数として関数を受け取ったり、 データ構造(特に、フック変数や属性リスト)内の関数を探して funcallapplyを使ってそれを呼び出すことは一般的です。 関数引数を受け付ける関数を しばしばファンクショナル(functionals)と呼びます。

場合によっては、ファンクショナルを呼び出すときには、 引数としてなにもしない関数(no-op)を指定できると有用です。 つぎのものは、2種類のなにもしない関数です。

— Function: identity arg

この関数はargを返し、副作用を持たない。

— Function: ignore &rest args

この関数は引数を無視し、nilを返す。