2008-01-09
Practical Common Lisp (22)
Practical Common Lisp 第5章5. Functionsを読んでメモしてみています。
半挫折気味です(笑)、気力が…。
Keyword Parameters
- オプショナル引数は便利だが、キーワード引数を使うとそれだけでは解決できないこともできる。
- &optional、&restの後だったらどこでも使える。
(foo) ==> (NIL NIL NIL) (foo :a 1) ==> (1 NIL NIL) (foo :b 1) ==> (NIL 1 NIL) (foo :c 1) ==> (NIL NIL 1) (foo :a 1 :c 3) ==> (1 NIL 3) (foo :a 1 :b 2 :c 3) ==> (1 2 3) (foo :a 1 :c 3 :b 2) ==> (1 2 3)
- 上記のように引数定義の順番ではなく、キーワードの名前と指定した値が対になる。キーワードを省略した場合は、&optionalのようにデフォルト値が使われる。また、同様にsupplied-pも使用可能。
- 外向のインターフェースとしては、指定した名前を使用し、内部では別の名前で処理したい場合、下記のように書ける。
(defun foo (&key ((:apple a)) ((:box b) 0) ((:charlie c) 0 c-supplied-p)) (list a b c c-supplied-p)) ;=> (foo :apple 10 :box 20 :charlie 30) ==> (10 20 30 T) ; :appleで値を受けとるが、内部では、aに結び付けられているので、aで参照。
PCLとは無関係な個人的な深追いと混乱メモ
CLtL2を読んでいたら、キーワードについてさらに詳しい(というか自由度の高い)使い方が説明されていたのでメモ
PCLでの例のように(:apple a)という風に記述すれば、内部では違う名前で扱えるわけですが、
(defun foo (&key ((:apple a) 0)) `(apple -> ,a) (foo :apple 10) ;=> (apple -> 10)
キーワードで使うシンボルは、キーワードパッケージのシンボルでなくても良いみたいで、
(defun foo (&key ((apple a) 0)) `(apple -> ,a )
とも書けます。
それで、呼び出しはどうなるのかと言えば、
(foo 'apple 1) ;=> (apple -> 1) (foo :apple 1) ;=> エラー
となり、定義に使用したキーワードが属するパッケージのシンボルである必要があるようです。
上記のようにパッケージ名を省略すれば、カレントパッケージになるわけですが、見た目で混乱するので、たとえば、cl-userのシンボルを使うとすると、
(defun foo (&key ((cl-user::apple a) 0)) `(apple -> ,a ) (foo 'cl-user::apple 1) ;=> (apple -> 1)
となります。
(defun foo (&key foo) (print foo))
をややこしく書くと、
(defun foo (&key ((keyword::foo foo))) (print foo))
ということみたいです。
しかし、キーワードにキーワードパッケージ以外を指定するような状況ってどういうのがあるんでしょう…。
お題: 西暦 to 和暦
今回の問題は、西暦を和暦に直す問題。といっても明治以降で対応すれば良し、とのこと。
しかし、明治6年までは太陰暦だったらしく、その辺をどう対応するのかはお題ではふれられていないので、意見が分かれている感じ。
…自分は対応しないということで、作成。
しかし、いつも下手なコードを投稿しているけれど、我ながら、今回はいつもに増してひどい気がするなあ(;´Д`)。
こういう予め決められたパラメータが多く出現するような問題の場合、パラメータの扱いをどうしたら良いのかが、いまいち分からない…。