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)
(symbolp i)
until (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
(length string)
for i below (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
"this is a sentence. this is another sentence.")
(tokenize-sentence => ("this" "is" "a" "sentence"), 19
"this is a sentence")
(tokenize-sentence => ("this" "is" "a" "sentence"), NIL
遷移制御
なし。
グローバル環境においてloop-finish
が fbound
かどうかは実装依存です。 しかしloop-finish
を再定義したりシャドウすることについては、 COMMON-LISP
パッケージのシンボルを グローバル環境下においてfbound
するようなことと 同等の制限があります。 loop-finish
をloop
の外で使用したときの結果は未定義です。
なし。