シンプルなサンプル関数(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])
角カッコ(square bracket)は&optional
と&rest
、およびそれらに続く変数が省略できることを示します。
この関数の呼び出しではrequired-varsのそれぞれにたいして、実際の引数が要求されます。0個以上のoptional-varsにたいして実際の引数があるかもしれませんが、ラムダ式が&rest
を使用していなければ、その個数を超えて実際の引数を記述することはできません。&rest
が記述されていれば、追加で任意の個数の実際の引数があるかもしれません。
optionalやrest変数にたいして実際の引数が省略されると、それらのデフォルトは常にnil
になります。関数にたいして引数に明示的にnil
が使用されたのか、引数が省略されたのかを区別することはできません。しかし関数のbodyが、nil
を他の有意な値が省略されたと判断することは自由です。substring
はこれを行います。substring
の3つ目の引数がnil
なら、それは文字列の長さを使用することを意味します。
Common Lispに関する注意: Common Lispではオプションの引数が省略されたときに使用するデフォルト値を指定できる。Emacs Lispでは、引数が明示的に渡されたかを調べる
supplied-p
変数はサポートされない。
例えば引数リストは以下のようになります:
(a b &optional c d &rest e)
これはa
とb
は最初の2つの実引数となり、これらは必須です。さらに1つまたは2つの引数が指定された場合には、それらは順番にc
とd
にバインドされます。1つ目から4つ目の引数の後の引数はリストにまとめられて、e
にそのリストがバインドされます。したがって2つしか引数が指定されなかった場合にはc
、d
、e
はnil
になります。2つまたは3つの引数の場合にはd
とe
はnil
です。引数が4つ以下の場合には、e
はnil
になります。正確に5つの引数に明示的にnil
が指定された場合には、e
にたいして他の単一値が与えられたときのように、引数のnil
が1要素のリスト(nil)
としてe
に与えられます。
オプションの引数の後ろに必須の引数を指定する方法はありません —
これは意味を成さないからです。なぜそうなるかは、この例でc
がオプションでd
が必須な場合を考えてみてください。実際に3つの引数が与えられたとします。3番めの引数は何を指定したのでしょうか?
この引数はcなのでしょうか、それともdに使用されるのでしょうか?
両方の場合が考えられます。同様に&rest
引数の後に、さらに引数(必須またはオプション)をもつことも意味を成しません。
以下に引数リストと、それを正しく呼び出す例をいくつか示します:
(funcall (lambda (n) (1+ n)) ; 1つの必須: 1) ; これは正確に1つの引数を要求する ⇒ 2 (funcall (lambda (n &optional n1) ; 1つは必須で、1つはオプション: (if n1 (+ n n1) (1+ n))) ; 1つまたは2つの引数 1 2) ⇒ 3 (funcall (lambda (n &rest ns) ; 1つは必須で、後は残り: (+ n (apply '+ ns))) ; 1つ以上の引数 1 2 3 4 5) ⇒ 15