引数解決

引数解決

制御構文または制御式でない統合演算形式が実行されると、引数解決 (argument resolution) が行われる。引数解決の過程では、演算指定子および引数を別の値に置き換えて引数解決を継続するか、または、何らかの方法で引数解決を終了する。演算指定子と引数を別の値に置き換えて引数解決を継続することを引数変換 (argument conversion) という。引数解決の過程のうち、同一の演算指定子および引数を用いる過程を、試行 (trial) という。

終端要因 (terminal factor) とは、引数解決を終了させる方法のことである。終端要因には以下のものがある。

終端要因のうちカプセルとプリミティブ演算を総称してホスト演算 (host operation) という。

引数変換要因 (argument conversion factor) とは、演算指定子および引数を別の値に置き換える方法のことである。引数変換要因には以下のものがある。

終端要因と引数変換要因をあわせて引数解決の要因 (factor) という。引数解決の要因には以下のものがある。このリストは優先順位が高い順に示す。

  1. force 引数解決ディレクティブ
  2. コンティニュエーション
  3. カプセル
  4. ストレージ
  5. 手続き
  6. プリミティブ演算
  7. suggest 引数解決ディレクティブ
  8. コンテキスト識別子変換
  9. ブーリアン型の false へのフォールバック

引数解決の試行では、有効な要因のうち最も優先順位が高いものが実行される。そのような要因が引数変換要因であれば、演算指定子と引数を新しいものに置き換えて、引数変換の試行を新たに開始する。また、そのような要因が終端要因であれば、その要因ごとに決められた方法で引数解決を終了する。

引数解決の要因となる制御構文は引数解決ディレクティブ (argument resolution directive) である。forcemain 制御構文と suggestmain 制御構文は引数解決ディレクティブである。

引数解決ディレクティブを除く要因

この節では引数解決の要因のうち引数解決ディレクティブでないものについて述べる。

演算指定子がコンティニュエーションであるとき、コンティニュエーションを実行する。すなわち、現在の動的環境を破棄し、コンティニュエーションとして保存されている動的環境を用いてインタープリターの動作を続行する。

演算指定子がカプセルであるとき、カプセルを実行する。すなわち、そのカプセルが持つ、ホスト言語で定義された手続きを実行する。

演算指定子がベクトルであり、そのベクトルをアドレスとするセルに値が記憶されているとき、引数解決を終了する。統合演算式の値は、そのセルの値である。

演算指定子がベクトルであり、そのベクトルをアドレスとする手続きが登録されているとき、引数解決を終了し、手続きを実行する。統合演算式の値は、手続きの戻り値である。

演算指定子がベクトルであり、そのベクトルをアドレスとするプリミティブ演算が登録されているとき、プリミティブ演算を実行し、引数解決を終了する。統合演算式の値は、プリミティブ演算の戻り値である。

コンテキスト識別子変換は以下の手順で行う。まず、演算指定子と垂直でないコンテキスト識別子を探す。そのようなコンテキスト識別子が存在しないか、または、そのようなコンテキスト識別子を持つコンテキストに親が存在しないならば、この要因は無効である。演算指定子と垂直でないコンテキスト識別子が存在し、かつ、そのコンテキストに親が存在するならば、演算指定子からそのコンテキスト識別子と平行な成分を除き、そのコンテキストの親のコンテキスト識別子を演算指定子に加算する。

他のすべての要因が無効であれば、統合演算式の値をブーリアン型の false として、引数解決を終了する。

引数解決ディレクティブ

この節では引数解決ディレクティブ forcesuggest について述べる。引数解決ディレクティブ forcesuggest は、多くの性質が共通するが、引数解決の要因としての優先順位が異なる。

引数解決ディレクティブは引数 hint, group, if, side effect, evaluate, next を取る。if 引数と evaluate 引数は必須である。evaluate 引数には統合演算式を記述する必要がある。引数 hint, group, side effect, next は省略可能である。

引数解決ディレクティブが実行されると、まず最適化ヒンティングが判断される。続いて group 引数が計算される。group 引数を計算する過程では引数解決ディレクティブは無効である。引数解決ディレクティブのヒエラルキーにより、この引数解決ディレクティブが有効であると判断されたならば、if 引数が計算される。

引数解決ディレクティブが「有効である」とは、以下のすべてを満たすことである。

この規則で有効とされた引数解決ディレクティブは、side effect 引数、evaluate 引数族 (arguments)、next 引数が計算される。これらの引数は以下のように計算される。

これらの計算を終えたら、演算指定子を evaluate 引数の演算指定子の値に置き換え、引数の値を evaluate 引数の引数の値に置き換えて、引数解決の新たな試行を行う。引数の値を置き換えるとき、evaluate 引数に記述されていない引数の値はそのまま保持される。また、もとの引数には存在しないが、evaluate 引数に記述されている引数は、新たに追加される。

引数解決ディレクティブの最適化ヒンティング

引数解決ディレクティブの最適化ヒンティング (optimization hinting) は、有効な引数解決ディレクティブを高速な方法で絞り込むことで、引数解決の計算量を削減する言語機能である。高速化ヒンティングはオプションであり、実装によってはこれを単に無視する。

引数解決ディレクティブの hint 引数は、イニシャライズ実行で計算され、キャッシュされる。hint 引数の値はベクトルまたは有限集合である必要がある。

引数解決の試行では、演算指定子または引数の値のうちベクトルであるものが、最適化ヒンティングの比較対象となる。これらの比較対象のいずれかと、引数解決ディレクティブの hint 引数で指定されたベクトルのいずれかが一致すれば、その引数解決ディレクティブは有効と判断される。また、hint 引数が記述されていない引数解決ディレクティブは常に有効とみなされる。

引数解決ディレクティブのヒエラルキー

引数解決ディレクティブのヒエラルキーとは、引数解決ディレクティブの引数を計算する過程で、引数解決ディレクティブを有効にするかどうかを判断する仕組みである。引数解決ディレクティブのヒエラルキーの対象となる引数は、引数 if, side effect, nextevaluate 引数族である。hint 引数と group 引数を計算する過程では、引数解決ディレクティブは常に無効である。

引数解決ディレクティブのヒエラルキーを使用するには、まず、引数解決ディレクティブの group 引数で、引数解決ディレクティブをグループに所属させる。group 引数の値はベクトルである必要がある。group を省略した引数解決ディレクティブは mainmain グループに所属する。

次に、hierarchy プリミティブ演算で引数解決ディレクティブのヒエラルキーを指定する。hierarchy プリミティブ演算は引数 highlow を取る。いずれの引数もベクトルである必要があり、これらの引数は引数解決ディレクティブのグループに対応する。引数 highlow により、あるグループが他のグループよりも高位 (hierarchically-higher) または低位 (hierarchically-lower) であることが示される。

引数解決ディレクティブのヒエラルキーを指定するために、hierarchy プリミティブ演算に加えて same hierarchy プリミティブ演算を使用できる。same hierarchy プリミティブ演算は main 引数を取り、この引数は有限集合である必要がある。same hierarchy プリミティブ演算は、指定された複数のグループのヒエラルキーが等しいことを意味する。

グループ A, B, C があり、AB よりも高位であることを A > BAB のヒエラルキーが等しいことを A = B と表記すると、以下が成り立つ。

また、引数解決ディレクティブのヒエラルキーは非反射的である。すなわち、グループは自分自身に対して高位ではない。

グループ A がグループ B よりも高位であるとき、グループ A の引数解決ディレクティブの引数 if, side effect, nextevaluate 引数族を計算する過程で、グループ B の引数解決ディレクティブが有効になる。そうでなければ、これらの引数を計算する過程で、引数解決ディレクティブは無効である。

引数解決ディレクティブのヒエラルキーが循環する、すなわち、A > B かつ B > A である場合の動作は予測できない。

引数解決ディレクティブの next 引数

引数解決ディレクティブの next 引数は、もし省略されていなければ、引数解決の次回の試行に影響を与える。前回の試行で next 引数の値が omit force allmain 有名ベクトルであれば、今回の試行では、 force 引数解決ディレクティブが無効になる。また、前回の試行で next 引数の値が omit force sequentiallymain 有名ベクトルであれば、今回の試行では、force 引数解決ディレクティブのうち、前回の試行で有効になった引数解決ディレクティブよりも後方に記述されているものが無効になる。

互換性についての注意 過去の言語仕様との互換性のため、next 引数に omit force allmain 有名ベクトルのかわりに omit forcemain 有名ベクトルを使用することができる。この仕様は将来の言語仕様では削除される可能性がある。

前回の試行で next 引数の値が storage, procedure, primitive (それぞれ姓が main である有名ベクトル) であれば、今回の試行では、それぞれストレージ、手続き、プリミティブ演算のみが有効な要因となる。

引数解決で使用できる引数

この節では、引数解決の過程で、コンテキスト引数と引数解決時引数がどのような値を持つか述べる。

コンテキスト引数の値は、引数解決の過程であっても、現在のコンテキストにより決定されることに変わりはない。

引数解決の過程では、verb 引数解決時引数の値は、引数解決の対象になっている統合演算式の演算指定子の値である。また、offset 引数解決時引数の値は、引数解決識別子、すなわち、引数解決を開始するとき作成される無名ベクトルである。その他の引数解決時引数の値は、引数解決の対象になっている統合演算式の引数の値である。これらのいずれにも当てはまらない引数解決時引数の値はブーリアン型の false である。

(参照透明性最適化)

互換性についての注意 参照透明性最適化は言語仕様から削除された。