ほとんどのループは1個かそれ以上のfor
節に支配される。for
節は束縛される変数を記述すると当時に、これらの変数がループ
中にどのようにステップされるか、また通常はこれらの変数に基づいた
終了条件を記述する。
語as
は語for
の同義語である。この語の後には変数名が続き、
望む繰り返しの種類を記述するfrom
やacross
のような語が
続く。Common Lispでは、句being the
がときどき繰り返しの型の前に
来る; このパッケージではbeing
とthe
はともに付加的である。
語each
はthe
の同義語であり、それに続く語は単数でも
複数でもよい: ‘for x being the elements of y’や
‘for x being each element of y’のように。どちらのフォームを
使うかは純粋にスタイルの問題である。
変数はlet
によるかにようにループの周りで束縛される:
(setq i 'happy) (loop for i from 1 to 10 do (do-something-with i)) i ⇒ happy
for var from expr1 to expr2 by expr3
このfor
節の型は数え上げのループを作る。3個の副項のそれぞれは
付加的だが、節が数え上げの節だとマークされるように少なくても1個の
項がなければならない。
3個の式はそれぞれ変数の開始値、終了値、ステップ値である。ループは、
expr1からexpr2(を含む)までを既定では上方に(expr3は
正数でなければならない)数える。from
項を省略した場合、ループは
0から数える; to
項を省略した場合、ループは止まらずに永久に数える
(もちろん、他のループ節によって止まらない限り); by
項を省略した
場合、ループは1のステップで数える。
ループの方向を示すために、語from
をupfrom
または
downfrom
に置き換えることができる。同様に、to
を
upto
またはdownto
に置き換えることができる。たとえば、
‘for x from 5 downto 1’はx
が順に5から1までの整数を
持ちながら5回実行する。また、to
をbelow
またはabove
に置き換えることもできる。これは制限を含むのではないことを除いて
upto
やdownto
にそれぞれ似ている:
(loop for x to 10 collect x) ⇒ (0 1 2 3 4 5 6 7 8 9 10) (loop for x below 10 collect x) ⇒ (0 1 2 3 4 5 6 7 8 9)
数え下げのループのためであっても、by
は常に正数である。
なんらかの種類のfrom
値が数え下げのループのためには必須である;
‘for x downto 5’はそれ自身まったく正しいループ節ではない。
for var in list by function
この節は、順にlistのすべての要素でvarを繰り返す。by
項を指定した場合、functionがcdr
の代わりにリストを
横切るために使われる; それは1個の引数をとる関数でなければならない。
たとえば:
(loop for x in '(1 2 3 4 5 6) collect (* x x)) ⇒ (1 4 9 16 25 36) (loop for x in '(1 2 3 4 5 6) by 'cddr collect (* x x)) ⇒ (1 9 25)
for var on list by function
この節はlistのすべてのコンスセルでvarを繰り返す。
(loop for x on '(1 2 3 4) collect x) ⇒ ((1 2 3 4) (2 3 4) (3 4) (4))
by
がある場合、on
式がリストでなければならないという
理由はない。たとえば:
(loop for x on first-animal by 'next-animal collect x)
ここでは(next-animal x)
は“動物”xをとり、動物の列
(と仮定されたもの)の中の次のものを戻すか、xが列の最後の動物の
場合はnil
を戻す。
for var in-ref list by function
これは普通のin
節と似ているが、varは単に一時変数ではなく、
リストの要素上のsetf
可能な“参照”になる。たとえば:
(loop for x in-ref my-list do (incf x))
は正しくmy-list
のそれぞれの要素の値を1つ増やす。この節は標準
Common Lispへの拡張である。
for var across array
この節はarrayのすべての要素でvarを繰り返す。arrayは ベクタまたは文字列でなければならない。
(loop for x across "aeiou" do (use-vowel (char-to-string x)))
for var across-ref array
この節は、varを要素上のsetf
可能な参照として配列上を
繰り返す; 上記のin-ref
を参照のこと。
for var being the elements of sequence
この節はsequenceの要素上で繰り返す。sequenceはリストか
ベクタ、文字列でなければならない。型は実行時に
決定されなければならないので、これはin
またはacross
よりもいくぶん効率が悪い。節には、var2が要素の連続する
インデックスに束縛されるようにするために、追加の項
‘using (index var2)’が続いてもよい。
この節の型はloop
マクロの古い版からとられており、最新のCommon
Lispにはない。より古いマクロの‘using (sequence ...)’項は
サポートされていない。
for var being the elements of-ref sequence
この節は、varを要素上のsetf
可能な参照として列上を繰り返す;
上記のin-ref
を参照のこと。
for var being the symbols [of obarray]
この節は、すべてのinternされたシンボルまたはobarray中のすべての シンボル上を繰り返す。ループは、varを順にそれぞれのシンボルに 束縛して実行される。シンボルは不定の順序で訪問される。
一例として、
(loop for sym being the symbols when (fboundp sym) when (string-match "^map" (symbol-name sym)) collect sym)
は、‘map’で始まる名前を持つすべての関数のリストを戻す。
Common Lispの語external-symbols
やpresent-symbols
も
認められるが、Emacs Lispではsymbols
と同等である。
重要でない実装の制限のために、一つのloop
の中にシンボル、
ハッシュ表、キーマップ、オーバレイ、インターバル上で繰り返す、
1つ以上のfor
節を持つと正しく動作しない。幸いにも、
そうすることが有用なことはきわめてまれだろう。for ... to
や
while
のような他の節とこれらの節の型の一つを混ぜることは正しい
ことである。
for var being the hash-keys of hash-table
この節はhash-tableのエントリ上で繰り返す。それぞれのハッシュ表
エントリに対して、varはそのエントリのキーに束縛される。
‘the hash-values’をその代わりに書いた場合、varはエントリの
値に束縛される。varやvar2がハッシュ表エントリの
2つのそれぞれの部分に束縛されるように、その節に追加の項
‘using (hash-values var2)’(hash-values
はthe
に続く語の反対の語である)が続いてもよい。
for var being the key-codes of keymap
この節はkeymapのエントリ上で繰り返す。GNU Emacs 18と19では、
キーマップは連想リストまたはベクタであり、キーコードは整数または
シンボルである。Lucid Emacs 19ではキーマップは特殊な新しいデータ
型であり、キーコードはシンボルまたはシンボルのリストである。繰り返しは
入れ子になったキーマップや受け継いだ親のキーマップには入らない。
キーコードではなくキーに束縛されたコマンドにアクセスするために
‘the key-bindings’を使うことができる。コードと束縛の両方に
アクセスするためにusing
節を加えることができる。
for var being the key-seqs of keymap
この節はkeymapとその入れ子になったキーマップで定義されるすべての キー列上で繰り返す。varはEmacs 18では文字列の値を、Emacs 19では ベクタの値をとる。文字列やベクタはそれぞれの繰り返しで 再利用されるので、それらをいつまでも保ちたいならば コピーしなければならない。同様にコマンド束縛を得るために ‘using (key-bindings ...)’節を加えることができる。
for var being the overlays [of buffer] …
この節はEmacs 19の“オーバレイ”またはLucid Emacsのバッファの
“エクステント”上で繰り返す(節extents
はoverlays
の
同義語である)。Emacs 18の元では、この節は1度も繰り返さない。of
項が省略された場合、現バッファが使われる。この節は、付加的な
‘from pos’や‘to pos’項も受け入れるが、指定した
リージョンを重ねるオーバレイへの節に制限する。
for var being the intervals [of buffer] …
この節は不変のテキスト属性を持つバッファのすべてのインターバル上で
繰り返す。変数varは開始位置と終了位置のコンスに束縛され、
そこではある開始位置は常に前の終了位置と等しい。この節はof
や
from
、to
、property
項を許す。そこでは後の項は
指定された属性のみに検索を制限する。of
項はバッファか文字列を
指定できる。この節はGNU Emacs 19のみで有用である; 他の版では、すべての
バッファや文字列は1つのインターバルから成る。
for var being the frames
この節はすべてのフレーム上、すなわちEmacsファイル上で開いている
Xウィンドウシステムのウィンドウで繰り返す。この節はEmacs 19の元でのみ
動作する。節screens
はframes
の同義語である。フレームは、
selected-frame
から始まるnext-frame
の順序で訪問される。
for var being the windows [of frame]
この節は現フレームか指定されたframeの(Emacsの意味での)ウィンドウ
上で繰り返す(Emacs 18では常に1つのフレームだけがあり、of
項はそこでは許されない)。
for var being the buffers
この節はEmacsのすべてのバッファ上で繰り返す。それは ‘for var in (buffer-list)’と同等である。
for var = expr1 then expr2
この節は一般の繰り返しを行なう。ループを最初に通るとき、varは expr1に束縛される。2回目やそれに続く繰り返しでは、それは expr2(varの古い値を参照してもよい)を評価した値に設定される。 たとえば、これらの2つのループは実際に同じである:
(loop for x on my-list by 'cddr do ...) (loop for x = my-list then (cddr x) while x do ...)
このfor
の型はどんな種類の終端条件も含まないことに注意せよ;
上記の例は、いつループが終わるかを言うためにそれとwhile
節を
結合する。
then
項を省略した場合、expr1は初期設定とそれに続く設定の
両方に使われる:
(loop for x = (random) when (> x 0) return x)
このループは、正数を得るまで(random)
関数から乱数を取得し続けて、
その後戻る。
1つの列にいくつかのfor
節を含む場合、それらは(let*
や
setq
のように)順次に扱われる。節を結合するために代わりに
語and
を使うことができ、その場合は(let
やpsetq
のように)並列に処理される。
(loop for x below 5 for y = nil then x collect (list x y)) ⇒ ((0 nil) (1 1) (2 2) (3 3) (4 4)) (loop for x below 5 and y = nil then x collect (list x y)) ⇒ ((0 nil) (1 0) (2 1) (3 2) (4 3))
第1のループでは、y
は前の節で設定されたばかりのx
の値に
基づいて設定される; 第2のループでは、x
とy
は同時に
設定されるので、y
はループを通して前回から残されたx
の値に
基づいて設定される。
loop
マクロの他の機能として分配があり、それは
defmacro
によって提供される分配と概念として類似している。
すべてのfor
節のvar部分は、単なる変数の代わりに変数の
リストとして与えることができる。ループ実行中に生成される値は
リストでなければならない; リスト中の値は対応する変数に格納される。
(loop for (x y) in '((2 3) (4 5) (6 7)) collect (+ x y)) ⇒ (5 9 13)
ループ分配では、変数よりも多くの値がある場合は残りの値は無視され、
値よりも多くの変数がある場合は残りの変数は値nil
を取得する。
nil
が変数名として使われた場合、対応する値は無視される。分配は
入れ子になってもよいし、(x . y)
のような変数のドットリストも
許される。