気が付けばかれこれ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)
こういう書き方なら問題ないようです。