第7回 慢性的CL勉強会[予習]

気が付けばかれこれ2週間もエントリーを投稿していませんでしたが、生きています。
サイクロンゆのはな一号機(自転車)の後輪が壊れて修理に1万円取られたり、
戦国ランスにはまりすぎて廃人になったり色々ありましたが、一応生きています。


「The Common Lisp Cookbook」の「The Loop Macro
を読み終わったので適当にまとめておきます。
*全体として*
説明よりもソースコード嫁!
という感じでした。
冒頭で「最も文書化されていない(least documented)」と書きながら、
ここでも説明が少ないというのには笑いました。
*内容のまとめ*
Loopマクロとは:
– Common Lispの中で最も価値があり、もっとも文書化されていない。
Loopマクロの価値:
(mapや再帰と比べて)
– 強力
– コンパクト
– 読みやすい
Loopマクロを成す4つの部分:
– 変数の設定(これは繰り返される)の式
– 繰り返しを終了させる条件の式
– 繰り返しごとに何かをする式
– 繰り返しを抜ける前に何かをする式
*試してみた*

[21]> (loop for x in '(a b c 1 2 3) thereis (numberp x) do (print x)) A B C T [22]> (loop for x in '(a b c) thereis (numberp x) do (print x)) A B C NIL

thereisは直後に書いた式がnil以外になるとループを抜け、tを返すようです。
全ての繰り返しでnilになれば最終的にnilを返すようです。

[23]> (loop for x in '(a b c 1 2 3) never (numberp x) do (print x)) A B C NIL [24]> (loop for x in '(a b c) never (numberp x) do (print x)) A B C T

neverは直後に書いた式がnil以外になるとループを抜け、nilを返すようです。
全ての繰り返しでnilになれば最終的にtを返すようです。

[19]> (loop for x in '(1 2 3 a b c) always (numberp x) do (print x)) 1 2 3 NIL [20]> (loop for x in '(1 2 3) always (numberp x) do (print x)) 1 2 3 T

alwaysは直後に書いた式がnilになるとループを抜け、nilを返すようです。
全ての繰り返しでnilにならなければ最終的にtを返すようです。
これら3つがwhenとreturnを組み合わせたものというのは大体納得できるのですが、
最終的に返す値を決めるには、これら3つを使わない場合、どうやって指定するんでしょうか。

[31]> (loop for x in '(a b c) never (numberp x) collect x) *** - (LOOP FOR X IN '(A B C) NEVER (NUMBERP X) COLLECT X): ambiguous result: (SYSTEM::LIST-NREVERSE #:ACCULIST-VAR-4350) from COLLECT X T from NEVER (NUMBERP X)

上記の最終的に返す値の話が絡んでいるかは分かりませんが、
never等とcollectを組み合わせるのはまずそうです。

[32]> (loop for x in '(a b c 1) when (numberp x) return x collect x) 1 [33]> (loop for x in '(a b c) when (numberp x) return x collect x) (A B C)

こういう書き方なら問題ないようです。

Leave a Reply