バイトごとに
三つのバグが直り、二つの出力はついに比べる価値があった:リファレンスコンパイラがコンパイルしたプログラムと、自分自身によってコンパイルされたコンパイラがコンパイルした同じプログラム。それらは同一だった —— 近いのでも等価なのでもなく、同じバイトが同じ順で —— そしてどちらを走らせても正しい答えを生んだ。それが bootstrap fixpoint で、言語が自分自身について言える最も強いことだ。ここが、いまのところ、地図の終わりだ:約束でなく、鏡を覗いて自分が変わっていないと見出したコンパイラで。
テストはこの Part の初めから同じで、いまやついに完全に走らせられた。プログラムを取る。リファレンス コンパイラ —— interpreter の下で走る、信頼された、正しいやつ —— でコンパイルし、出力を取っておく。それから 自分自身によって WebAssembly バイナリにコンパイルされ、いまやそのバイナリとして走っているコンパイラで 同じプログラムをコンパイルし、その出力も取っておく。二つを並べる。Part まるごとが回っていた問いは、それら が一致するか、だった。
同一
した —— そしてその言葉がときに帯びる緩い意味でなく。二つの出力は同じ順の同じバイトで、最後の一文字まで 見分けられず、差はきっかりゼロだった。そしてそれは空のものの一致でなかった:それぞれが実質的なプログラム、 数千行の生成コードで、完全に一致していた。それから最後のチェック、好奇心を事実に変えるやつ:出力自身が 走らされ、正しい答えを生んだ。だから鎖はあらゆる環で保った —— コンパイラ、自分自身によってコンパイルされた コンパイラ、そしてその二番目のコンパイラが生んだプログラム、三つとも正しく、真ん中の二つが同一。それが bootstrap fixpoint だ。自分自身によってコンパイルされバイナリとして走り、自分自身のリファレンス出力を 正確に再生するコンパイラは、単に自分自身を emit できるという弱い意味で self-hosting なのでない。強い意味で self-hosting だ:複製は忠実で、そしてそれを証明できる、バイトごとに。
なぜ強い意味が数える意味なのか
なぜこれが持つ価値のある主張なのかを明確にする価値がある、なぜなら弱いほうがそれと取り違えやすいから。 自分自身の valid なバイナリを emit するコンパイラは、そのコード生成器が自分自身のソースを扱えることを 示した —— 実の結果だが、構造的なもの、validator が受け入れる形についての。それは、そのバイナリが走ると コンパイラが振る舞うように振る舞うかについて何も言わない。強い主張はまさにその gap を閉じる。それは emit されたコンパイラが単に well-formed なだけでなくコンパイラとして正しい、その出力を元のと見分けられない ほど忠実だと言う。この Part のすべてはその二つの主張の間の空間に住んでいた —— overflow、欠けた末尾呼び出し、 鏡だけが見せられる三つのバグ —— そしてそのどれも、言語が完全に自分自身で立つよう、interpreter の寛大な スタックも型推論器の環境的な知識も支えなしに、させられるまで見えなかった。fixpoint はその支えが完全に 取り除かれ、言語が倒れない瞬間だ。
回帰テスト、それが真のままであるように
一度証明された事実は、静かに真でなくなりうる事実だ。だから fixpoint はテストスイート自身に書き込まれた: 各実行で、スイートはリファレンスコンパイラと自己コンパイルしたコンパイラでプログラムをコンパイルし、二つの 出力がバイト同一だと assert する。証明はもはや起きたことでない;それはチェックされる性質で、忠実な複製を 壊す将来のどんな変更も、静かにずれるでなく大声で失敗する。マイルストーンはリリースになり、リリースはこの Part が建てたものを運んだ:保証された末尾呼び出し、三つの自己コンパイル修正、そしてそれらすべてを守る チェック。言語ができる最も強い主張が、いまや保つのに最も安い。
まるごとが何についてだったか
ここが地図の縁で、そこに達するために越えた地を振り返るのに良い場所だ。十の Part、そしてそのすべての下に 一つの方法。難しい問いが紙の上で精密な断片に narrowed され、信頼される前に小さな実験で試され、それから その粗い縁が現れるまで実の何かに対して dogfood された。新しい問題が現れたとき、最初の一手はもっと発明する でなくすでに建てた機構に寄りかかること —— native になったメモリモデル、一家を育てたコンパイル時特殊化、 一度に一つの構文を通して threaded された末尾位置ビット。抑制は背後に証拠のある行為だった:建てられなかった ロック、投資されなかった LLVM backend、急がれるでなく地平に名指されて残された feature。そして保証は両方向に 正直に保たれた —— そこにない健全性を決して主張せず、そこにある縁を決して隠さず。
bootstrap fixpoint は一区切りにふさわしい場所だ、なぜならそれはその方法まるごとが言語自身に向けられたもの だから。連載のほとんどで言語はテストする側、web アプリと CLI とドキュメントを建てそれらの痛みを見つける 道具だった。fixpoint でそれはテストされる側になる —— 自分自身のソースを手渡され、自分自身を正確に再生する よう求められ、その最も要求の厳しい負荷の下で、もっと優しい何もが決して surface しなかった欠陥を明かすよう させられる。それは通った。思想と最小コアとして始まった言語が、自分自身を、忠実に、コンパイルし、そうすると 証明できる。地図にはまだ縁があり、開発はそれを描き直し続ける。だがこれは実の summit で、偽のものでない —— コンパイラは鏡を覗いて自分が変わっていないと見出した —— そしてここが、この建設の記録が終わるところだ。