Next: Function Documentation, Previous: Simple Lambda, Up: Lambda Expressions [Contents][Index]
シンプルなサンプル関数(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
が記述されている場合、追加で任意個の実際の引数があるかもしれません。
optionaや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
はnil
になります。2つまたは3つの引数の場合、d
はnil
です。引数が4つ以下の場合、e
はnil
になります。
オプションの引数の後ろに必須の引数を指定する方法はありません —
これは意味を成さないからです。なぜそうなるかは、この例で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