セルフホスティングコンパイラが新しい言語の通過儀礼と見なされるのはなぜですか?


30

尊敬に値するために、言語がセルフホスティングコンパイラを使用するか、少なくとも持っていることを人々が期待していると、今では多くの場所で聞いています。

これがなぜなのか興味があります。コンパイラは書くべき非常に重要なソフトウェアのようであり、すべての言語がそれらを作成するのに適しているわけではないと思います。より良い結果をもたらす何かに努力を費やす方が理にかなっていますか?


17
「コンパイラは書くのに非常に重要なソフトウェアのように思えます。すべての言語がそれらを作成するのに適しているわけではないと思います。」:これは、新しい言語でコンパイラを書こうとする、つまり言語がタスク次第であることを証明する。
ジョルジオ14年

13
特別な目的の言語でない限り、コンパイラーを書くのに適していない言語は、おそらく私がやりたいことにはあまり適していません。
CodesInChaos 14年

3
知る限り、これはFortranには必ずしも当てはまりません。いくつかのFortranコンパイラ(例えばgfortranからGCCが ...)されていない Fortranでコーディングされました。
バジルスタリンケビッチ14年

回答:


29

より良い結果をもたらす何かに努力を費やす方が理にかなっていますか?

どのような?

コンパイラの良いところは、多くの依存関係がないことです。これにより、非常に大規模または多様な標準ライブラリをまだ持っていない可能性が高い新しい言語の候補となります。

さらに良いことに、彼らはさまざまなものを必要とすると同時に、よく研究されています。多様性は、例が言語のさまざまな部分をテストすることを確実にするのに役立ちます。よく研究されているということは、比較する他のコンパイラがあることを意味します-また、自分が何をしているのかを知っているアカデミックな種類に対してより多くの信用を与えます。

そして、コンパイラは膨大な作業のように見えますが、大まかな計画ではコンパイラはかなり小さいです。言語実装者が新しい言語で以前にやったことさえできなかったら、どのように斬新なことをするのでしょうか?標準ライブラリやIDEのような本当に大きなものをどのように扱うのでしょうか?


副次的な注意として、私は素晴らしいにもかかわらず、コンパイラが別の言語で書かれているかもしれない様々な理由がまだあることを言及したいと思います。たとえば、ほとんどのjavascriptエンジンはjavascriptで記述されていません。これには多くの理由があります:他のソフトウェアとの統合、既存のライブラリ/依存関係へのリンク、優れたツール、パフォーマンス、レガシーコード...時々、言語の自己コンパイルは素晴らしいですが、それでもコアコンパイラを維持する意味があります別の。しかし、言語自体は理にかなっています。通常、エコシステム全体を再開発する余裕がないというだけです。
dagnelies

2
@arnaudそして、JavascriptコンパイラはJavascript環境を必要とするという事実。JavascriptはJavascript環境を必要とするため、Javascript環境はオペレーティングシステムによって提供されないため(<逆説的に>)、 Javascriptで書かれていませんでした)。
Qix 14

3
@Qix en.wikipedia.org/wiki/Bootstrapping_%28compilers%29しかし、主にそれを使用する理由はありません。貧弱な言語として広く知られていますが、ブラウザは状況を制御しているため、コンパイルに使用しません。
デン14

3
「多くの依存関係を持たない」という主張については、よくわかりません。これは、コンパイラフロントエンドに当てはまる場合があります。しかし、ASTを取得するとすぐに、独自のオプティマイザーとコードジェネレーターを実行することは、有望なルートのようには見えません。最新の最適化手法には、サードパーティのライブラリを使用したい洗練されたフォーマルロジックエンジンが必要であるという事実は別として、GCCのような業界の強みの基盤の上に構築するのではなく、新しい言語ごとに車輪を再発明する理由はありませんまたはLLVM。
5gon12eder

30

コンパイルされている言語でコンパイラーを使用するという目標は、多くの場合、「自分のドッグフードを食べる」という習慣の一部です。サポートするモジュールとツールの言語、コンパイラー、エコシステムが「本気の作業に十分」または「生産準備完了」であるとみなすことを世界に示します。

また、言語、コンパイラ、およびランタイム設計に最も近いものを、彼らが下したすべての決定の影響、および選択した開発の優先順位(いぼおよびすべて)に直接直面させるという好意的な効果もあります。これはしばしば、理論的に言語環境を理解するだけでなく、ハード/リアルワード条件のるつぼで言語/ツールを使用した広範な実務経験を持つコアグループにつながります。


1
完全性のために:あなた自身のドッグフードを食べる。参照犬供給(ADJ)に又はドッグフーディング(動詞)
クイックス

17

人々は、1つの主な理由で新しい汎用言語を作成します。彼らは、他のすべての言語について少なくとも1つのことを嫌います。これが、非常に多くの言語が普及しない理由です。あなたはあなたのプログラミングの生活を改善するだろう言語の素晴らしいアイデアを持っていますが、少なくとも一つの方法であなたを悩ませる言語で最初の実装をしなければなりません。セルフホスティングにより、その古い迷惑な言語で作業する必要がなくなります。だからこそ、言語のクリエイターはそのステップに向かって努力し、それを大きなマイルストーンと見なしています。

多くの言語機能は紙の上ではよく見えますが、実際のプロジェクトでそれらの機能を使い始めると、それらの制限が見え始めます。一例として、多くの言語は最初は適切なユニコードをサポートしていません。大規模なプロジェクトを完了すると、こうした状況の多くが発生して対処されたことを確認できます。また、セルフホスティングコンパイラは、他のプロジェクトと同様に優れたプロジェクトです。そのため、言語の作成者以外の人々はそれを大きなマイルストーンと見なしています。

それはそれが注目に値する唯一のマイルストーンであることを意味しません。データベース統合、グラフィカルインターフェイス、ネットワークなど、コンパイラによって実行されない機能があります。


(ネイティブ)言語があるような気がした言語、それは自分自身をコンパイルすることができますし、(それが機能する現代のOSのほとんどのために必要なタスクの大半/全てを包含するので)Linuxカーネルはそれに移植することができます。
Qix 14

ただし、コンパイラーを作成するのに十分なUnicodeサポートは実際には必要ありません。
パエロエベルマン

11

Steve Yegge 、多少間接的にこの問題に対処する素晴らしいブログ記事書きました

大きなポイント1:コンパイラーは、コンピューターサイエンスのほとんどすべての側面を網羅しています。開始する前に、コンピュータサイエンスのカリキュラムで学んだ他のすべてのことを知る必要があるため、これらは上位レベルのコースです。データ構造、検索と並べ替え、漸近的なパフォーマンス、グラフの色付け?すべてそこにあります。

Knuthが(ちょうど)コンパイラーの教科書として始まったにもかかわらず、数十年にわたって彼の記念碑的な(そして終わりのない) "コンピュータープログラミングの芸術"に取り組んでいる理由があります。カール・セーガンが「ゼロからアップルパイを作りたいなら、まず宇宙を発明しなければならない」と言ったのと同じように、コンパイラーを書きたいなら、まずコンピューター科学のほぼすべての側面に対処しなければなりません。

つまり、コンパイラが自己ホスト型であれば、何をしていても、必要なことを確実に実行できるはずです。逆に、言語でコンパイラを作成しなかった場合、誰かにとって本当に重要な何かを見逃す可能性が高くなります。言語の実装者は、それらすべての問題について考える必要のあるプログラムを作成する必要がなかったからです。

大きなポイント#2: 30,000フィートから、驚くほど多くの問題がコンパイラのように見えます。

コンパイラはシンボルのストリームを取得し、いくつかのドメイン固有の事前定義ルールに従って構造を把握し、それらを別のシンボルストリームに変換します。かなり一般的ですね。まあ、そうだろう。

Visual C ++チームに所属しているかどうかに関係なく、コンパイラの一部のように見える何かをする必要があることは非常によくあります。文字通り毎日やっています。

他のほとんどの職業とは異なり、プログラマーはツールを使用するだけでなく、独自のツールを作成します。(スキルの不足、または他のツールを構築するための使用可能なツールの不足により)ツールを作成できないプログラマーは、他の誰かが提供するツールに制限されて、永久に障害になります。

言語が、シンボルのストリームを受け取り、ルールを適用し、それを別のシンボルのストリームに変換できるプログラムを「作成するのに適していない」場合、かなり制限された言語のように聞こえますが、有用ではありません私に。

(幸いなことに、シンボルの変換に不向きなプログラミング言語は多くないと思います。Cはおそらく現在使用されている最悪の言語の1つですが、Cコンパイラは通常自己ホスト型であるため、誰も停止することはありません。)

個人的な経験から、Yeggeが言及していない3番目の理由(彼は「なぜ自分をホストするのか」について書いていなかったため)。あなたはしているが、コンパイラを書くとき、それはあなたがすべての時間を意味構築(あなたがいないだけで毎回それを実行して)、あなたはまともなサイズのコードベース(コンパイラ自体)に対して正しく動作させると、仕事にそれに依存します。

今月は、比較的新しく有名な非自己ホスト型コンパイラ(おそらくどちらかを推測できます)を使用してきましたが、2日間はセグメンテーション違反なしでは行けません。デザイナーが実際にどれだけ使わなければならなかったのだろうか。


8

言語Xのコンパイラをセルフホストにしたい場合、最初に言語Xの入力を受け取り、アセンブリコード、または中間コードを吐き出すように、Yなどの他の言語で実装する必要があります。コンパイラが実行されているマシンのオブジェクトコード。ある時点でYで記述されたコードをXに翻訳するため、言語Yをできるだけ言語Xに似たものに選択する必要があります。

ただし、必要以上に言語Yでコンパイラを記述したくないので、最初は言語のサブセットのみを実装し、冗長な構成要素を排除します。'C'型言語の場合は、whileですが、forまたはdo whileはありませんもしいないが、ケースまたは第三オペアンプ。構造体、共用体、列挙はありません。あとは、言語Xのパーサーと初歩的なコードジェネレーターを作成するのに十分な言語です。次に、出力を確認します。再び。

これが機能したら、言語Yで記述されたコンパイラソースを言語Xに書き換え、言語Yで記述されたコンパイラを使用して言語Xソースをコンパイルできます。出力は、新しい言語Xで記述された新しいコンパイラになります。言語Xをコンパイルします。つまり、自己ホスト型になりました。ただし、言語Yの言語のサブセットのみを実装したため、完全ではありません。

そこで、不足している機能を追加し、各機能(または機能グループ)が正しいコードを生成することをテストします。つまり、機能がコンパイラに実装されると、新しい機能を使用してテストプログラムを記述し、それらをコンパイルおよびテストできますが、まだコンパイラソースで使用しないでください。新しい機能が検証されると、コンパイラソース自体でこれらの新しい機能を使用できます-言語サブセットで記述された元のコードの一部を置き換える可能性があります-新しい機能を備えたバージョンを使用してコンパイラソースを再コンパイルします。

これで、言語に新しい機能を追加するメカニズムが得られました。機能のコード生成が正しく検証されたら、次世代のコンパイラ自体で使用できます。

60年ほど前、コンピューターが最初に登場したとき(そしてマイクロプロセッサーが最初に到着したとき)、初期コンパイラーの実装に適した言語Yは他にありませんでした。そのため、最初のコンパイラはアセンブリコードで作成する必要があり、十分なコンパイラが実行されると、アセンブリコードは新しい言語で作成されたバージョンに置き換えられます。アセンブラもありませんか?プロセッサ全体が別のレベルに落ち、最初はアセンブラがマシンコードで記述されました。


2

コンパイラを書くために適切に設計されていないが、他の目的のために適切に設計されたプログラミング言語を作成することは可能ですか?

SQLのような言語を見ると、答えはイエスだと思います。しかし、その性質の言語は一般的な目的ではありません。


1
受け入れられたチャレンジ:SQLでCコンパイラーを作成します。
Qix

2

誰がそれを言うの?...とにかく、それは単なる意見です。一部の人は同意するかもしれませんが、一部の人は同意しないかもしれません。一部の言語にはコンパイラが組み込まれていますが、そうでない言語もあります。なんでも。

とはいえ、言語が「自己コンパイル」できるのであれば、それは良いエクササイズ/概念実証だと思う...それはただ...いい...そしてそれは言語がいくつかの複雑なことをするのに適していることを証明している。

また、すばらしいにもかかわらず、コンパイラが別の言語で記述されている可能性のあるさまざまな理由があります。 たとえば、ほとんどのjavascriptエンジンはjavascriptで記述されていません。これには多くの理由があります:他のソフトウェアとの統合、既存のライブラリ/依存関係へのリンク、優れたツール、パフォーマンス、レガシーコード...時々、言語の自己コンパイルは素晴らしいですが、それでもコアコンパイラを維持する意味があります別の。しかし、言語自体は理にかなっています。通常、エコシステム全体を再開発する余裕がないというだけです。


2

ClangはC ++で書かれています。Objective-CでClang Objective-Cコンパイラを書き直すことはそれほど難しくありませんが、それではまったく役に立ちません。C ++コンパイラの変更は、Objective-Cでやり直す必要があり、その逆も同様です。なぜ?

現在、Clang Swiftコンパイラがあります。確かにそのコンパイラはSwiftで書き直すことができます。しかし、それはどんな目的でしょうか?言語がコンパイラを書くのに十分強力であることを実証するには?Swiftでコンパイラを記述できるかどうかは気にしません。Swiftでユーザーインターフェイスを作成できれば、人々気にします。

さまざまな言語をコンパイルするように簡単に適応できる十分にテストされたコンパイラーがある場合、1つの異なる言語で書き換えることによりコンパイラーでの作業が容易にならない限り、異なる言語に書き換えることはまったく無意味です。また、たとえばClangをSwiftで記述するのが理にかなっている場合、Clang C、C ++、およびObjective-Cコンパイラはすべて Swiftで記述されます。

あるプログラミング言語でコンパイラを作成できることを証明するよりも重要なことがあります。


1

それは、言語が複雑な文字列処理を処理し、別の言語に翻訳/自身を解釈できることを示しています。

コンパイラ(最初の大きなプロジェクト)を作成するプロセスでは、問題が前面に出てきます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.