失敗は Verse における制御フローです。
ブール 値の true/false でプログラムのフローを変更する他のプログラミング言語と異なり、Verse は成功または 失敗 になる 式 を使用します。これらの式は 失敗する可能性がある式 と呼ばれ、失敗コンテキスト のみで実行できます。
制御フロー で失敗を使用することは、処理を複製する必要がなく、ちょっとしたミスを避けられるということです。
たとえば、他の言語では 配列 の インデックス が有効であるかどうかチェックしてからそのインデックスの配列要素にアクセスする必要があります。他の言語ではこれがエラーのよくある原因になっています。
Verse では、これを避けるために検証とアクセスが結合されています。
次に例を示します。
if (Element := MyArray[Index]):
Log(Element)
失敗する可能性がある式
失敗する可能性がある式は、成功して [値](verse-glossary#値 を生み出すか、失敗して値を返さない 式 です。失敗する可能性がある式の例として、配列へのインデックス処理 (無効なインデックスでは失敗するため)、演算子 の使用 (2 つの値の比較など) があります。
作成するコードは、デフォルトでは失敗する可能性が考えられていません。たとえば、失敗できる 関数 を作成するには、エフェクト 指定子 <decides>
をその関数の定義に追加する必要があります。 現在は、<decides>
を使用するとき、<transacts>
を追加する必要もあります。`.
失敗する可能性がある式の完全なリストについては、Verse の 式 のリストを参照してください。
失敗コンテキスト
失敗コンテキストとは、失敗する可能性がある式を実行できる コンテキスト です。このコンテキストでは、式が失敗した場合に何が起きるかが定義されます。失敗コンテキスト内でなんらかの失敗があると、全体のコンテキストが失敗します。
失敗コンテキストは、関数の引数や block
式内の式など、ネストされた式を失敗式にすることができます。
Verse における失敗コンテキストの便利なところは、投機的 実行 の形式になっていることです。つまり、コミット することなくアクションを試せます。式が成功したとき、式のエフェクトが コミット されます。たとえば、変数の値の変更があります。式が失敗すると、式のエフェクトは ロールバック され、式が評価されなかったようになります。
このようにして、変更がどんどん加えられる一連のアクションを実行できます。ただし、これらのアクションはどこかで失敗すると、すべて元に戻ります。
このように動作させるには、失敗コンテキストで呼び出すすべての関数に <transacts>
エフェクト指定子が必要となります。
ユーザー定義関数には、デフォルトで transacts
エフェクトがありません。明示的な <transacts>
指定子をそれらの定義に追加する必要があります。 一部のネイティブ関数も transacts
エフェクトがなく、失敗コンテキストでコールできません。
transacts
のないネイティブ関数の例には、BeginSound()
メソッドがある audio_component があります。サウンドが開始され、停止されるとしても、通知される可能性があります。
次のリストでは Verse でのすべての失敗コンテキストを示します。
-
if
式の条件。if (test-arg-block) { … }
-
for
式のイテレーション式とフィルタ式。for
は各イテレーションに失敗コンテキストを作る点で特別なことに注意してください。イテレーションが ネスティング している場合、その失敗コンテキストもネスティングします。式が失敗すると、一番内側の失敗コンテキストが停止し、それを囲むイテレーションがあれば、次のイテレーションが続けられます。for (Item : Collection, test-arg-block) { … }
-
<decides>
エフェクト指定子がある関数またはメソッドのボディ。IsEqual()<decides><transacts> : void = { … }
-
not
演算子のオペランド。not expression
-
or
に対する左オペランド。expression1 or expression2
-
option
型である変数の初期化。option{expression}