Local Macro LOOP-FINISH
loop-finish <引数なし> => |
loop-finishマクロは、 拡張されたloopフォームの中で レキシカルに使用することができ、 そのフォームを「普通に」終了させます。 つまり、文脈的に最も内側の拡張されたloopフォームを 繰り返しの終わりの位置に遷移させます。 これはどんなfinally項の実行も許しますし、 蓄積された結果の返却も行われます。
;; loopは終了しますが、蓄積されたcountは返却されます。
(loop for i in '(1 2 3 stop-here 4 5 6)
      when (symbolp i) do (loop-finish)
      count i)
=>  3
 
;; 前のloopは次のものと同等です。
(loop for i in '(1 2 3 stop-here 4 5 6)
      until (symbolp i)
      count i)
=>  3
;; LOOP-FINISHはさまざまな状況に使用できますが、
;; 最も必要とされるのはloopがトップレベルで行うもの
;; (UNTILかWHENが同様なものとして使われる)を使用せずに
:; 退出が必要となるような状況があった場合や、
;; または終了の必要性が検出されてから実際に終了が行われるまでに
;; 何らかの計算が行われなければならないような場合です。
(defun tokenize-sentence (string)
  (macrolet ((add-word (wvar svar)
               `(when ,wvar
                  (push (coerce (nreverse ,wvar) 'string) ,svar)
                  (setq ,wvar nil))))
    (loop with word = '() and sentence = '() and endpos = nil
          for i below (length string)
          do (let ((char (aref string i)))
               (case char
                 (#\Space (add-word word sentence))
                 (#\. (setq endpos (1+ i)) (loop-finish))
                 (otherwise (push char word))))
          finally (add-word word sentence)
                  (return (values (nreverse sentence) endpos)))))
=>  TOKENIZE-SENTENCE
(tokenize-sentence "this is a sentence. this is another sentence.")
=>  ("this" "is" "a" "sentence"), 19
(tokenize-sentence "this is a sentence")
=>  ("this" "is" "a" "sentence"), NIL遷移制御
なし。
グローバル環境においてloop-finishが fboundかどうかは実装依存です。 しかしloop-finishを再定義したりシャドウすることについては、 COMMON-LISPパッケージのシンボルを グローバル環境下においてfboundするようなことと 同等の制限があります。 loop-finishをloopの外で使用したときの結果は未定義です。
なし。