引数解決

引数解決

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

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

引数変換要因 (argument conversion factor) には以下のものがある。

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

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

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

引数解決の要因となる制御構文は引数解決ディレクティブ (argument resolution directive) である。forcesuggest は引数解決ディレクティブである。また、引数解決の過程で実行されるが、引数解決の要因にはならない制御構文を擬似引数解決ディレクティブ (pseudo argument resolution directive) という。この文書では、擬似引数解決ディレクティブを引数解決ディレクティブに含める。

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

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

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

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

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

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

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

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

引数解決ディレクティブ

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

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

引数解決ディレクティブが実行されると、まず group 引数が計算される。group 引数を計算する過程では引数解決ディレクティブは無効である。引数解決ディレクティブのヒエラルキーにより、この引数解決ディレクティブが有効であると判断されたならば、if 引数が計算される。実装によっては、group 引数と if 引数はマルチスレッドで実行されることがある。ただし、同一の引数解決ディレクティブの group 引数と if 引数は、この順に計算される。

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

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

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

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

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

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

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

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

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

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

次に、hierarchy プリミティブ演算で引数解決ディレクティブのヒエラルキーを指定する。hierarchy プリミティブ演算は引数 highlow を取る。いずれの引数もベクトルである必要があり、これらの引数は引数解決ディレクティブのグループに対応する。引数 highlow により、あるグループが他のグループよりも高位 (hierarchically-higher) または低位 (hierarchically-lower) であることが示される。引数解決ディレクティブのヒエラルキーは推移的である。すなわち、グループ A がグループ B よりも高位であり、グループ B がグループ C よりも高位であるとき、グループ A はグループ C よりも高位である。また、引数解決ディレクティブのヒエラルキーは非反射的である。すなわち、グループは自分自身に対して高位ではない。

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

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

この節では、引数解決の過程で、コンテキスト引数 (argument を姓とする複合名) と引数解決時引数 (resolution argument を姓とする複合名) がどのような値を持つか述べる。

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

引数解決の過程では、引数解決時引数 verb は、引数解決の対象になっている統合演算式の演算指定子の値である。また、引数解決時引数 offset の値は、引数解決を開始するとき作成される無名ベクトルである。この無名ベクトルは、引数解決を終了する要因が手続きであれば、その手続きのコンテキスト識別子として使われる。引数解決を終了する要因が手続きでなければ、その固有ベクトルは解放される。その他の引数解決時引数の値は、引数解決の対象になっている統合演算式の引数の値である。これらのいずれにも当てはまらない引数解決時引数の値はブーリアン型の false である。

参照透明性最適化

引数解決ディレクティブと擬似引数解決ディレクティブの if 引数は、実装によっては、参照透明性を仮定した最適化が行われる。引数解決ディレクティブと擬似引数解決ディレクティブの if 引数の内部に記述されている式は、式のシンタックスと、その式の戻り値との対応がキャッシュされる。式のシンタックスがキャッシュにヒットすれば、その式を評価することなく、キャッシュされている戻り値が使われる。キャッシュは引数解決の試行ごと、かつ、引数解決ディレクティブのグループごとに分離される。