loop
(loop clause...) (拡張形式) または (loop form...) (単純形式)
ANSI loop マクロの限定的なサブセットです。既存の反復コア (内部のブロック境界で包まれた do* 相当のステップ処理) に展開されるため、インタプリタと両コンパイラで同一に動作します。
トップレベルの各サブ形式がすべて複合形式 (リスト) の場合、loop は 単純ループ になります。それらの形式を return で脱出するまで永遠に繰り返します。
それ以外の場合は、節 (clause) から構成される 拡張ループ です。サポートする節は次のとおりです。
- 数値ステップ:
for VAR from LO [to|upto|below|downto|above HI] [by STEP](upfrom/downfromも可。fromのない上限キーワードは 0 から開始)。 - リストステップ:
for VAR in LIST [by FN]とfor VAR on LIST [by FN](VARには分配束縛パターンも指定可能)。 - シーケンスステップ:
for VAR across SEQはVARを文字列の各文字、またはベクタの各要素に順に束縛します。 - 汎用ステップ:
for VAR = INIT [then STEP](VARには分配束縛パターンも指定可能)。 - ローカル変数:
with VAR [= INIT](VARには分配束縛パターンも指定可能。andで連結したwithの束縛は並行に行われます)。 - 集約:
collect、append、nconc、sum、count、maximize、minimize。それぞれ省略可能なinto VARを取れます。 - 終了判定:
thereis EXPR、always EXPR、never EXPR。 - 制御:
while/until(記述位置で判定)、repeat N、do FORM...、return EXPR、本体形式内の(loop-finish)、initially FORM...、finally FORM...、および条件節when/if/unless(省略可能なelseとendを伴い、選択された節では判定値をitで参照可能)。
複数の for 節は一緒にステップし、最も短いドライバが尽きた時点でループは終了します。これがインデックス付き map の定石です。逐次的な節は順にステップします (後の節の初期化式・ステップ式は直前の節が生成した値を参照でき、最初に尽きたドライバでステップは停止するため、for x in xs for a = (f x) then (g a x) は CL と同様に動作します)。
and は for 節をひとつのグループに連結し、初期化とステップを前回の反復の値に対して計算します (do* に対する do の並行ステップに相当)。
集約と数値範囲はよくあるケースを直接表現できます。
本体節の後 (または in/on/across のように本体の先頭で変数を代入する for の後) に置いた while/until は、その記述位置で判定するため、現在の要素を参照できます。
when/if/unless の内側では、アナフォリックな it で判定式の値を参照できます。
thereis は式が最初に非 nil になった値を返します。always/never は最初の失敗で nil に短絡し、正常終了時には t を返します。これらによる早期脱出は return と同様に finally をスキップします。
本体形式内の (loop-finish) は反復を正常終了させます。finally は実行され、ループの結果値も生成されます (両方をスキップする return とは異なります)。
for/with の変数には分配束縛パターン — 変数の真リスト (ネスト可能。nil はその位置を無視) — を指定できます。
for ... across は文字列を 1 文字ずつ、またはベクタを 1 要素ずつ走査します。
being のパッケージ形式 — for VAR being {the|each} {symbols|present-symbols|external-symbols} {of|in} PACKAGE — は受け付けますが 簡易版 です: rontolisp には実行時のインターンテーブルがないため、この節は解析され 空 のシーケンスを反復します。本体は実行されず、集約結果は nil になります。ロード時にパッケージを走査するライブラリ (cl-who の hyperdoc テーブルなど) がエラーなくロードできるようにするためのものです:
制限事項: being のハッシュテーブル反復 (hash-key/hash-value) と named/return-from は未対応です。分配束縛パターンは変数の真リストに限られます — リーダーがドット対構文を受け付けないため (a . b) のようなドットパターンは使えず、ラムダリストキーワードも認識されません。(loop-finish) は文の位置 (式の途中は不可) に置く必要があり、ネストした反復形式の内側では使えません。thereis/always/never はデフォルト結果への集約とは併用できません (into を使ってください)。into を伴わない集約節はすべて同種でなければならず、収集系の節は結果リストをソース順に構築します。