Common Lispの色々なループ
例によって、実践Common Lispで勉強中です。マクロの話に入る前にループの話が出てきたので忘れないうちにやっておく。
第7章で出てきたループ構文は以下の4つ。
- dolist
- dotimes
- do
- loop
dolist
これは、リストの内容を一つずつ変数に入れながらループを行います。foreach的な感じだと思う。以下の例は*num-list*変数に1〜5までの数字の入ったリストを用意しておき、dolistを使ってリストの要素を変数nに一つずつ格納してループを繰り返す処理になります。
CL-USER> (defvar *num-list* '(1 2 3 4 5)) *NUM-LIST* CL-USER> (dolist (n *num-list*) (print n)) 1 2 3 4 5 NIL
なかなか、よく使われるんじゃないかなと思う。
dotimes
これは決められた数だけ繰り返し処理を行いたいときに使うのかな。Rubyでいう3.times { print "a" }みたいなやつです。
以下の例では、変数*loop-count*の数だけ処理を繰り返すことになります。(例がよくないので上の例と結果は似てますが・・・)
CL-USER> (defvar *loop-count* 7) *LOOP-COUNT* CL-USER> (dotimes (n *loop-count*) (print n)) 0 1 2 3 4 5 6 NIL
do
で、本を読んだだけじゃよく理解できなかったやつがこのdoループ。フィボナッチ数列使った例っていわれてもわかんないので、以下に無意味だけどわかりやすい例を載せときますw
CL-USER> (do ((i 0 (1+ i)) ; 変数i 初期値:0 ステップ:i++ (j 10 (1+ j)) ; 変数j 初期値:0 ステップ:j++ (k 20 (1+ k))) ; 変数k 初期値:0 ステップ:k++ ((= i 10) (+ i j k)) ; 終了条件と戻り値 (format t "i: ~a j:~a k: ~a~%" i j k)) ; ループ毎に実行される処理 i: 0 j:10 k: 20 i: 1 j:11 k: 21 i: 2 j:12 k: 22 i: 3 j:13 k: 23 i: 4 j:14 k: 24 i: 5 j:15 k: 25 i: 6 j:16 k: 26 i: 7 j:17 k: 27 i: 8 j:18 k: 28 i: 9 j:19 k: 29 60
と、それでも結構分かりにくい。doの最初の引数には複数の変数を宣言することが出来る(上記コードの1〜3行目)。次の引数にはループの終了条件と戻り値を指定する(4行目)。最後の引数は、ループで毎回実行される処理を記述する(5行目)といった感じ。
こいつは、たくさんコード書いてそのうち馴れて行くんだろうね。
最後はloop。これはまた今度・・・。