loop - lisp-cookbook-ja/common-lisp GitHub Wiki
繰り返し(loop)
無限ループ
loopキーワードをなにも指定しなければ無限ループです。
(loop (print "hello")
(print (random 100)))
;-> "hello"
49
"hello"
37
...
シーケンス上でのループ
forキーワードでループ変数を宣言できます。 続けて in でリスト上を across でベクタ上を渡り歩きます。 ハッシュテーブルには being hash-keys of または being hash-values of を使います。
;; 奇数の要素のみ取り出して、その二乗した値をリストにして返します。
(loop for i in '(1 2 3 4 5) if (oddp i) collect (* i i))
;=> (1 9 25)
;; 文字コードが奇数の文字のみ取り出してリストにして返します。
(loop for i across "hello" if (oddp (char-code i)) collect i)
;=> (#\e #\o)
;; ハッシュテーブルを渡り歩きます。順序は定義されていません。
(loop for i being the hash-keys of (make-hash-table)
do (print i))
;; キーだけでなく値も参照したい場合は using で指定します。
(loop for i being the hash-keys of (make-hash-table)
using (hash-value j)
do (print (cons i j)))
複数のforを指定できますが、入れ子になるのではなく並列して処理されます。 最初に終端にきたところでループは終わります。
(loop for i in '(1 2 3)
for j in '(4 5)
do (print (cons i j)))
;-> (1 . 4)
(2 . 5)
;=> NIL
補助変数の導入
withキーワードでループ内変数を宣言できます。 初期値を指定しない場合はnilになります。 forと違い値は勝手に更新されません。
(loop with x = 1
with y
repeat 3
do (setf y x)
(print y))
ループ変数の型指定
of-type キーワードでループ変数の型を指定できます。 コンパイラが優秀であれば効率の良いコード生成の助けになるでしょう。
;; i の型を fixnum と宣言します。
(loop for i of-type fixnum from 0 to 10 do (print i))