シンプルなサンプル関数 (lambda (a b c) (+ a b c))
は3つの引数変数を指定しているため、3つの引数で呼び出す必要があります。2つの引数や4つの引数で呼び出そうとすると、wrong-number-of-arguments エラーが発生します(エラーを参照)。
特定の引数を省略できる関数を定義しておくと便利なことが多いです。例えば、substring
関数は文字列、開始インデックス、終了インデックスという3つの引数を受け取りますが、3番目の引数を省略した場合は、その文字列の length がデフォルトとなります。また、list や
+ 関数のように、不定数の引数を受け取れるようにすることも便利です。
関数呼び出し時に省略可能なオプション引数を指定するには、オプション引数の前にキーワード &optional を記述します。0個以上の追加引数のリストを指定するには、最後の引数の前にキーワード
&rest を記述します。
したがって、引数リストの完全な構文は次のようになります。
(required-vars... [&optional [optional-vars...]] [&rest rest-var])
角括弧は、&optional および &rest 節と、それに続く変数が省略可能であることを示しています。
関数の呼び出しには、required-vars それぞれに対して1つの実引数が必要です。optional-vars のうち0個以上に実引数を指定でき、ラムダリストで &rest
が使用されていない限り、それ以上の実引数を指定することはできません。その場合、任意の数の追加の実引数を指定できます。
オプション変数および rest 変数の実際の引数が省略された場合、それらは常に nil
がデフォルトとなります。関数側で、明示的な引数としての nil
と省略された引数を区別する方法はありません。ただし、関数本体では nil
を他の意味のある値の略記として扱うことができます。substring
がまさにこれに該当します。また、substring の第3引数としての nil は、指定された文字列の長さを使用することを意味します。
Common Lispに関する注記: Common Lispでは、オプション引数が省略された際に使用するデフォルト値を関数で指定できます。Emacs Lispでは常に
nilが使用されます。Emacs Lispでは、引数が明示的に渡されたかどうかを示すsupplied-p変数はサポートされていません。
例えば、次のような引数リスト:
(a b &optional c d &rest e)
a と b
を、必須である最初の2つの実引数にバインドします。さらに1つまたは2つの引数が指定された場合、c と
d がそれぞれそれらにバインドされます。最初の4つ以降の引数はリストにまとめられ、e がそのリストにバインドされます。したがって、引数が2つだけの場合は c、d、e が nil となり、2つまたは3つの引数の場合は
d と e が nil となり、4つ以下の引数の場合は e が nil となります。なお、e 用に明示的な nil 引数を指定してちょうど5つの引数が渡された場合、nil 引数は、e に対する他の単一の値と同様に、1つの要素
(nil) を持つリストとして渡される点に注意してください。
必須引数を任意引数の後に配置する方法はありません—それでは意味が通じないからです。なぜそうならざるを得ないのかを確認するため、例にある
c が任意で d
が必須であると仮定してみましょう。実際に3つの引数が与えられた場合、3番目の引数はどの変数に対応することになるでしょうか。c に使われるのか、それとも d
に使われるのでしょうか。どちらの可能性も考えられます。同様に、&rest
引数の後にさらに引数(必須か任意かを問わず)を設けることも意味をなしません。
引数リストと適切な呼び出しの例をいくつか挙げます。
(funcall (lambda (n) (1+ n)) ; One required: 1) ; requires exactly one argument. ⇒ 2 (funcall (lambda (n &optional n1) ; One required and one optional: (if n1 (+ n n1) (1+ n))) ; 1 or 2 arguments. 1 2) ⇒ 3 (funcall (lambda (n &rest ns) ; One required and one rest: (+ n (apply '+ ns))) ; 1 or more arguments. 1 2 3 4 5) ⇒ 15