たくさん寝太郎の寝床

料理とITと皿回しが好きなオタクのブログ

Lispの話(loopの使い方)

こんにちは、たくさん寝太郎です。


最近親知らずあたりが腫れていて微妙に痛いです。
2月に歯医者へ行った時は「綺麗に生えてるので別に抜かなくて良いですよ」と言われましたが、たまに親知らずで頰肉を噛んだりするので抜こうかなぁ...と悩んでいます。



今日はloopコマンドの使い方について学ぼうと思います。

loopコマンド

繰り返し処理をする時に使います。

(loop repeat 10 collect 1)

=>

(1 1 1 1 1 1 1 1 1 1)

repeatでループ回数指定、collectで1回ごとに集めるオブジェクトを指定します。

(loop for i from 1 to 10 collect i)

=>

(1 2 3 4 5 6 7 8 9 10)

forで変数指定、from ~ to ~で変数の初期値と終値を指定します。

(loop for i below 5 sum i)

=>

10

below nfrom 0 to n-1と同じ意味です。

(loop for i in '(1 3 5) sum i)

=>

9

inにリストを渡すことでリストの各要素について繰り返します。

(loop for i below 5 when (evenp i) do (print i))

=>

0
2
4

whenまたはifで変数の条件を指定します。(ifとwhenの違いがよく分かりませんが同じ意味なんでしょうか?)
doの後に処理を書くことで、任意の式を繰り返し実行できます。

whenを使うことで、「変数がある値になった時にループを終了する」といったことができます。

(loop for i from 0 do (print i) when (= i 2) return 'end)

=>

0
1
2
END


上で述べたloop文はどれも1変数でしたが、多変数のloop文も書くことができます。

(loop for x in '(1 2 3) for y in '(4 5 6) collect (+ x y))

=>

(5 7 9)

このように書いた場合、xとyは同時に変化します。
xとyの要素の個数が違う場合はどうなるか?」と気になったので試してみると次のようになりました。

(loop for x in '(1 2 3) for y in '(4 5 6 7) collect (+ x y))

=>

(5 7 9)

errorが返ってそうな気がしましたが、先ほどと同じ結果が返ってきました。
loopコマンド中に複数のforがある場合は要素数が少ない方に繰り返し回数が合わされるようです。





色々な例を学びましたが、loopには更にたくさんの用法があります。
他の使い方についてはその都度学んでいこうと思います。


ちなみに、loopコマンドは処理系ごとのloopマクロの実装に依存するため快く思わない人もいるようです。(有名な方だとPaul Graham氏)


これで10章の内容が終わりました。
年末までに読み終えられるよう頑張ろうと思います。