Special Operator THROW
throw tag result-form =>|
tag - catchのタグ、評価されます。
result-form - フォーム、下記の説明どおり評価されます。
throwは、tagとeqで等しいタグのcatchへ、 非局所的な制御の遷移を行います。
最初にtagが評価され、throwタグと呼ばれるオブジェクトを生成します。 そのあとresult-formが評価され、その値は保存されます。 もしresult-formが多値を生成したときは、その全ての値が保存されます。 もっとも近くにあるtagとeqで等しい throwタグを持つ有効なcatchに対して退出が行われます。 そのとき保存された値は、catchの返却値か多値として返されます。
throwによって開始される制御の遷移の実行についての説明は、 5.2. 終了地点への制御の遷移をご確認ください。
(catch 'result
(setq i 0 j 0)
(loop (incf j 3) (incf i)
(if (= i 3) (throw 'result (values i j))))) => 3, 9
(catch nil
(unwind-protect (throw nil 1)
(throw nil 2))) => 2下記の例ではbのcatchの上を最初のthrowによって通過しているため、 結果は未定義であり、したがって移植可能なプログラムは 動的エクステントが終了していると仮定してください。 catchタグの束縛はまだ解除されていないので、 これは2番目のthrowのターゲットです。
(catch 'a
(catch 'b
(unwind-protect (throw 'a 1)
(throw 'b 2))))下記の例は「The inner catch returns :SECOND-THROW」が出力され、 :outer-catchが返却されます。
(catch 'foo
(format t "The inner catch returns ~s.~%"
(catch 'foo
(unwind-protect (throw 'foo :first-throw)
(throw 'foo :second-throw))))
:outer-catch)
>> The inner catch returns :SECOND-THROW
=> :OUTER-CATCHなし。
もしthrowタグにマッチする有効なcatchタグがないときは、 unwindのスタックが実行され、 型control-errorのエラーが発生します。 もしエラーが発生した時は、 動的環境はthrowの地点で有効なものになります。
block, catch, return-from, unwind-protect, 3.1. 評価
catchとthrowは通常、 退出点が動的スコープのとき(例えば、 throwがレキシカルなcatchに囲まれていないとき)に使われ、 それに対してblockとreturn-fromは、 レキシカルスコープで十分のときに使用されます。