Common Lispの色々なループ

例によって、実践Common Lispで勉強中です。マクロの話に入る前にループの話が出てきたので忘れないうちにやっておく。

実践Common Lisp
実践Common Lisp
posted with amazlet at 09.03.23
Peter Seibel
オーム社
売り上げランキング: 131799

第7章で出てきたループ構文は以下の4つ。

  1. dolist
  2. dotimes
  3. do
  4. 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。これはまた今度・・・。