千四百八十四の注釈

どの probe も同じしわを報告し続けていた。多相パラメータには型注釈が要る、と。想定されていた修正 —— 双方向推論 —— は、大きくて危険な型システム作業としてリストに座っていた。設計する前に、センサス。255 本の example プログラム全部の注釈を数え、どれが本当に必須かをテストする。結果は問いを溶かした。1,484 のパラメータ注釈のほぼすべてがスタイルだった —— 素の整数パラメータも、ベクタの読み出しも、float リテラルも無注釈で推論が通り、作者自身の「すべての vec_get に ascription を書く」直近の習慣はカーゴカルトだと判明した。本当に注釈を要するパターンは正確に二つで、どちらも一行の workaround を持ち、一方は既に良い hint を備えていた。評決: 手術はしない。もう一方のパターンに hint を与え、双方向推論は数字を添えて棚に戻った —— 注釈が設計を飾るのでなく歪めるプログラムが現れるのを待つ。

meretype-inferenceergonomicslanguage-design

この二週間のどの probe も同じしわを提出した。プログラムのどこかで、多相パラメータが型注釈を 書かないと checker に受理されなかった、と。行列乗算にも一つ要り、台帳にも一つ要り、raytracer の ベクトル演算は全体が ascription 付きで書かれた。想定されていた修正には名前があった —— 双方向型 推論 —— そして大仕事リストに常設の項目があった。use-site の情報が一般化に凍結される前にパラメータへ 届くよう、型の流れ方を設計し直す。大きく、危険で、二千二百のテストの下で checker に触れる。それを 設計する前に、既に二度報われている同じ一手を打つ。問題を測る。

センサス

二百五十五本の example プログラム、二万四千行 —— この言語の dogfood 時代に書かれた全プログラム。 機械的なカウントで 1,484 のパラメータ注釈と約 150 のインライン ascription が見つかった。次に実証の 半分。各種類の代表的な注釈を剥がして、実際に何が失敗するかを見る。素の整数パラメータ、無注釈 —— 推論が通る。算術に使われるベクタの読み出し、ascription なし —— 通る。無注釈の関数に流れ込む float リテラル —— 通る。多相ヘルパ経由で組んだ top-level のテーブルを ascription なしで読み戻す、圧縮 コードに満ちていたまさにあの形 —— 通る。そこから、居心地の悪い、有用な発見が出た。私自身の直近の example にある九十箇所の vec_get ascription はカーゴカルトだった。どこかの古いバージョンがどこかで 必要とし、習慣が形成され、以来ずっと正しいコードを防御的な型で飾り続けていたのだ。センサスは半分は 言語の監査で、半分は作者の監査だった。

千ではなく、二つのパターン

本当に失敗するのは、正確に二つの形だと判明した。多相 binding を経由する float —— ヘルパは float が 届く前にパラメータを一般化し、デフォルトが int に落ち、呼び出し側でエラーになる。そして多相パラメータ への record update —— 更新の場所はどの record 型を組み直しているのか知る必要があり、一般化はそれを 既に消している。どちらも根は一つ。let 一般化が、型を留めたはずの制約より先に走る。どちらも同じ一行の workaround を持つ。そのパラメータ一つに注釈を書く。float の側は古典四重奏が見つけて以来、鋭い hint を 備えている —— エラーが defaulting の規則を説明し、二つの逃げ道を名指す。record の側には hint がまったく 無かった。エラーは「record update base must be a record value」と言い、残りはあなたに考えさせた。

手術の代わりに hint を

正直な算術はこうだ。双方向推論が消すのは、少数のプログラムに現れ、回避に一行ずつしか掛からない 二つの注釈パターンで、その代価は suite の全重量の下で checker の中核を作り直すこと。それは取引に ならない —— 今は。おそらく永遠に。注釈に飾られるのでなく、注釈に設計を本当に歪められた実プログラムが 現れない限り。だからこのリリースは最小の真の修正を積む。record update のエラーは float のものと同種の hint を持ち、workaround を例つきで名指す。そして大物は棚に戻る。ただし以前とは違う戻り方で —— 数字を 添えて。三つの調査が続けてこう終わった。namespace 化は測ったら安いと分かったので作られた。メモリ成長は 測ったら本物だが強制されていないと分かったので、崖の番地を書き留めて据え置かれた。そして双方向推論は 測ったら、作者自身がカーゴカルトの ascription で広めていた噂が大半だと分かった。まず測る。測定が たいてい、そのまま決定だ。

← Back to Mere: 言語を作る