&key の考察
LispでSocket作るときとか、他の様々な関数でもプロトタイプの中に&KEYというのがあることがある。ちょっとこれについての考察、というかメモ。
まず、自分でキーワードを使用した関数を定義するには、以下のようにする。
(defun keyword-func (&key a b c) (list a b c))
この例だと、キーワードを一つも引数に含まずにこの関数を呼び出すとエラーになる。
これを少し進化させてみる。
(defun keyword-func (&key (a 1) b c) (list a b c))
こうすると、引数にキーワードを一つも含まないで呼び出しても、a が 1 として扱われる。
CL-USER> (defun keyword-func (&key (a 1) b c) (list a b c)) KEYWORD-FUNC CL-USER> (keyword-func) (1 NIL NIL)
そして、キーワードにはもう一つ値を指定できる。上記例だと、a の 1 はデフォルト値の 1 なのか、実際に 1 を指定して呼び出されたのかが区別できない。その判定に使用される変数(?)も指定できる。
(defun keyword-func(&key (a 1 adefaultp) (b 2 bdefaultp) (c 3 cdefaultp)) (list a adefaultp b bdefaultp c cdefaultp))
これを実行すると以下のようになる。
CL-USER> (keyword-func) (1 NIL 2 NIL 3 NIL) CL-USER> (keyword-func :a 10 :b 20 :c 30) (10 T 20 T 30 T) CL-USER> (keyword-func :a 10) (10 T 2 NIL 3 NIL) CL-USER> (keyword-func :b 2) (1 NIL 2 T 3 NIL) CL-USER> (keyword-func :a 1 :b 2 :c 3) (1 T 2 T 3 T) CL-USER>
ただ、この書き方だと、キーワード引数以外の引数の扱いがよくわからなくなる。それについてはまた別の機会にやってみる。