この節は残りのループ節を記述する。
with var = valueこの節はループの周りである値をある変数に束縛するが、その他の点では ループ中にその変数を孤立させる。下記のループは基本的に同等である:
(loop with x = 17 do ...) (let ((x 17)) (loop do ...)) (loop for x = 17 then x do ...)
当然、変数varはループの残りでなんらかの用途に 使われるかもしれない。たとえば:
(loop for x in my-list with res = nil do (push x res)
finally return res)
このループは、resに蓄積されている新しいリストの先頭に
my-listの要素を挿入し、それからループの終わりにリストres
を戻す。その効果はcollect節の効果と類似しているが、要素は
末尾にではなくresの先頭に置かれていくという事実のために
逆順になる。
=項を省略した場合、その変数はnilに初期化される
(したがって上記の例の‘= nil’は不要である)。
withによって作られる束縛は、let*によってのように、
既定では順次である。ちょうどfor節のように、with節はその
代わりに束縛がletによって作られるようにするためにandと
結合されえる。
if condition clauseこの節は、指定された条件が真の場合だけ、それに続くループを実行する。
下記のclauseは蓄積であるべきである; doやreturn、
if、unless節。いくつかの節は、それらをandで
切り離して結合されてもよい。
これらの節には、elseと、条件が偽の場合に実行される1つまたは
複数の節が続いてもよい。すべての構文要素には、付加的に語end
(それは入れ子のifの中でelseやand
をあいまいでなくするために使われてもよい)が続いてもよい。
実際の条件式の非nilの値は、“then”部の中で名前itとして
利用できる。たとえば:
(setq funny-numbers '(6 13 -1))
⇒ (6 13 -1)
(loop for x below 10
if (oddp x)
collect x into odds
and if (memq x funny-numbers) return (cdr it) end
else
collect x into evens
finally return (vector odds evens))
⇒ [(1 3 5 7 9) (0 2 4 6 8)]
(setq funny-numbers '(6 7 13 -1))
⇒ (6 7 13 -1)
(loop <same thing again>)
⇒ (13 -1)
2つの節を“then”部に置くためのandの使用に注意せよ。その
1つはそれ自身if節である。endは、通常は付加的であるが、
elseが最も外側のif節を参照することを
明らかにするためにここでは必要だったことにも注意せよ。第1の場合、
ループはxの奇数と偶数のリストのベクタを戻す。第2の場合、奇数7は
funny-numbersの一つなのでループは早く戻る; 実際の戻り値は、
memq呼び出しの結果に基づく。
when condition clauseこの節は単にifの同義語である。
unless condition clauseunless節は、条件の意味が逆であることを除いてちょうどifに
似ている。
named nameこの節は、ループを囲む暗黙のブロックにnil以外の名前を与える。
nameはブロック名として使われるシンボルである。
initially [do] forms...このキーワードはループ自身が始まる前(しかしforやwithに
要求されるすべての変数がその初期値に束縛された後)に実行される1つかそれ
以上のLispフォームを導入する。initially節はどこにでも
現れることができる; いくつかある場合、それらはループに現れる順に
実行される。キーワードdoは付加的である。
finally [do] forms...これはループが終わった後(たとえば、forやwhileの要求で)に
実行されるLispフォームを導入する。initiallyやfinally節は
ループ構文要素のどこに現れてもよいが、それらはループのそれぞれ始まりや
終わりに(指定された順序で)実行される。
finally return formこれは、戻り値を得るためにループ終了後に実行されるべきform
について述べる(これやcollectやreturnのようないくつか他の
節がないと、ループは単にnilを戻すだろう)。forや
with、intoによって束縛された変数は、formが
実行されるときにその最後の値をまだ含んでいる。
do forms...語doには、ループ本体で暗黙のprognとして実行される任意の
数のLisp式が続いてもよい。この節の例の多くはdoの使用法を
説明する。
return formこの節は、ループが直ちに戻るようにする。それに続くLispフォームは
評価され、loopフォームの戻り値を与える。finally節は、
もしあったとしても実行されない。もちろん、returnは一般に
ifやunlessの内部で使われるが、それはトップレベルのループ
節での使用は、そのループは決して1度以上“ループ”に到達しないことを
意味するからである。
節‘return form’は‘do (return form)’(あるいは
ループが名付けられている場合はreturn-from)と同等である。
しかし、return節は若干効率的に実装されている。
loopへユーザ拡張を加える(たとえばsetfに対する
defsetfに比較できるような)高水準の方法はないが、この
パッケージは、与えられたシンボルがトップレベルループ節やfor節に
出会ったときにそれぞれ呼び出される関数であるcl-loop-handlerや
cl-loop-for-handlerと呼ばれる2つの属性を提供する。詳細は
ファイルcl-macs.elのソースコードを調べよ。
このパッケージのloopマクロはCommon Lispのそれと互換だが、
loop-finishやデータ型指定子のようないくつかの機能は
実装されていない。当然、キーマップやオーバレイ、インターバル、
フレーム、ウィンドウ、バッファ上で繰り返すfor節はEmacs特有の
拡張である。