6.8. kink/CONTROL

このモジュールは、基本的な制御構造をいくつか提供する。

6.8.1. CONTROL.while($continue? $body)

whileは、$continue?がtrueを戻すかぎり、$bodyをくりかえし呼び出す。

whileはまず$continue?を引数なしで呼び出す。$continue?がtrueを戻せば、whileは$bodyを引数なしで呼び出し、最初に戻る。$continue?がfalseを戻せば、whileは戻る。

事前条件

$continue?はboolを戻すサンクでなければならない。

$bodyはサンクでなければならない。

例

6.8.2. CONTROL.try($body $returned_cont $raised_cont)

tryは引数なしで$bodyを呼び出す。

$bodyの呼び出しが戻ったら、tryは、$bodyの戻り値を引数として、$returned_contを末尾呼び出しする。

$bodyの呼び出しが例外を投げたら、tryは、exceptionを引数として、$raised_contを末尾呼び出しする。

事前条件

$bodyはサンクでなければならない。

$returned_contはひとつの引数を取る関数でなければならない。

$raised_contはexceptionを取る関数でなければならない。

例

6.8.3. CONTROL.with_return($body)

with_returnは、関数$returnを引数として$bodyを呼び出す。$bodyの呼び出しの中で、サンク$exit_contを引数として$returnを呼び出すことができる。$returnが呼び出されると、$bodyの呼び出しはそこで中断し、with_returnは$exit_contを末尾呼び出しする。

$bodyの呼び出しが、$returnを呼ぶことなしに最後まで到達したら、with_returnは例外を投げる。

事前条件

$bodyは関数$returnを取る関数でなければならない。

例

gcdの再帰的な呼び出しはスタックを消費しない。なぜなら、gcdはwith_returnの末尾文脈で呼び出されており、これはgcdの末尾文脈でもあるからだ。つまり、これは末尾再帰である。

なおgcdは、with_returnを使わず、より単純に実装できる。

例: ネストした呼び出し

6.8.4. CONTROL.with_finally($body)

with_finallyは、関数$finallyを引数として$bodyを呼び出す。$bodyの呼び出しの中で、サンク$cleanupを引数として$finallyを任意回数呼び出すことができる。$cleanupは、次の状況で呼び出されることが保証される。

(1) $bodyの呼び出しが戻ったとき

(2) $bodyの呼び出しからCONTROL.with_returnの$returnによって脱出したとき

(3) $bodyが例外を投げたとき

$finallyがn回、サンク $cleanup_1, $cleanup_2 ,,, $cleanup_n を、この順番に引数として呼ばれたとき、これらのサンクは逆順で呼ばれることが保証される: $cleanup_n ,,, $cleanup_2, $cleanup_1

$cleanupの呼び出しを、CONTROL.with_returnで脱出してはならない。

結果

(1) $bodyの呼び出しが戻ったとき

どのcleanupサンクも例外を投げなければ、with_finallyは$bodyの呼び出しが戻した値を戻す。

ひとつ以上のcleanupサンクが例外を投げれば、それらの例外はひとつの例外としてチェーンされて、with_finallyはそのチェーンされた例外を投げる。

(2) $bodyの呼び出しからCONTROL.with_returnの$returnによって脱出したとき

どのcleanupサンクも例外を投げなければ、with_finallyは脱出を再開する。

ひとつ以上のcleanupサンクが例外を投げれば、それらの例外はひとつの例外としてチェーンされて、with_finallyはそのチェーンされた例外を投げる。

(3) $bodyが例外を投げたとき

どのcleanupサンクも例外を投げなければ、with_finallyは$bodyが投げた例外を投げる。

ひとつ以上のcleanupサンクが例外を投げれば、それら例外は$bodyが投げた例外のチェーンに追加されて、with_finallyはそのチェーンされた例外を投げる。

事前条件

$bodyは、関数$finallyを取る関数でなければならない。

例

6.8.5. CONTROL.with_return_finally($body)

with_return_finallyは、$returnと$finallyを引数として$bodyを呼び出す。

これは、with_returnとwith_finallyを、次のようにネストするのと同等である:

$returnは$bodyの呼び出しをその場で中断する。with_return_finallyは、$returnに渡されたサンクを末尾呼び出しする。

$finallyは、片付けサンクを登録する。片付けの意味論の詳細は、with_finallyを見よう。

事前条件

$bodyは、関数$returnと$finallyを取る関数でなければならない。

例