すべての言語はCで書かれていますか?


180

時々、異なる言語(C / C ++、C#)でプログラミングしているときに、この考えが思い浮かびます。

  • すべての言語はCプログラミング言語で書かれていますか?
  • C言語はすべての言語の母/父ですか?
  • 各コンセプト(OOPなど)はすべてCで実装されていますか?

私は正しい方向にいますか?


58
(多分ほとんどの)Cコンパイラは、Cで書かれている多く:@XLAnt
イェルクWミッターク

32
@Neil:C ++は何にもコンパイルしません。C ++は言語です。言語はコンパイルされませんが、コンパイラはコンパイルします。
ヨルグWミットタグ14

12
@XLAnt:そうは思いません。しかし、最初のOberonコンパイラーは、例えば、Oberonで作成され、Fortranに手動で翻訳されました(これはコンパイルの一種です)。このコンパイラーは、Fortranコンパイラーでコンパイルされ、生成されたOberonコンパイラーがOberonコンパイラーのコンパイルに使用され、その時点から、前のバージョンのコンパイラーが次のコンパイラーのコンパイルに使用されました。
ヨルグWミットタグ14

18
@Neilそれは本当にそれほどつまらないものではありません。正確です。言語は仕様です。コンパイラ、インタプリタ、ハイブリッドなどとして実装できます。言語のコンパイラ作成できますが、コンパイラは言語ではありません。リファレンス実装を除いてどこにも仕様が書かれていない言語があるため、問題は混乱を招くと思います。しかし、そのような場合でも、言語(つまり、著者が考えていた理想)は実装/コンパイラ/インタープリターなどとは異なると主張します。
アンドレスF。14年

21
Downvoters:これは明確な答えのあるかなり合理的な質問です。答えが「いいえ」であるということは、投票する理由にはなりません。代わりに、答えて説明することを検討してください。
アンドレスF。14年

回答:


207

番号。

OCaml、Haskell、SchemeのようなLisp方言、および他のいくつかの言語は、趣味言語の開発によく使用されます。

ユビキタス言語であるため、多くの言語がCで実装されており、レクサーパーサージェネレーター(yaccやbisonなど)などのコンパイラー作成ツールは十分に理解されており、ほぼユビキタスです。

しかし、C自体は、Cが最初に作成されたときには、Cで開発することはできませんでした。実際には、もともとはB言語を使用して開発されました。以前の言語(Fortranなど)は通常、ネイティブアセンブリ言語またはCが存在するずっと前にマシンコードを使用してブートストラップされていました。

無関係に、 OOPのような言語パラダイムは一般に言語に依存しませんたとえば、関数型パラダイムは、プログラミング言語が存在するずっと前に数学の基盤として開発されました(Alonzo Churchによって)。手続き型および構造化プログラミングのパラダイムは、ジョン・フォン・ノイマンのような理論家の数学的研究から生まれました。オブジェクト指向は、いくつかの異なる無関係な努力によって開発されました。一部はラムダ計算(機能的パラダイム)から、一部はAlan KayによるXerox PARCのSmallTalkのような動的プログラミングシステムからです。

Cは、これらのアイデアが生まれてから数十年後の物語のほんの一部です。


40
最初のCコンパイラは明らかにCで記述できなかったのは事実ですが、今では確かに可能です。
reirab

17
@reirab可能かつ真。GCCはCで記述され、GCCを使用して通常コンパイルされます。
ダークホッグ14

9
もちろん、GCCは現在、C ++に書き換えられているが、それは最初のCコンパイラは、C言語で書かれたことができなかったという事実ほど重要ではありません
greyfade

10
@greyfade gccはしばらくの間Cではありませんでした。「今書き直されている」のではなく、「2年以上C ++で書かれている」(それよりも古いですが、マージが起こってC ++に移行した)。

13
@greyfadeは「CではなくC ++機能を備えた」C ++の定義ではありませんか?
KutuluMike 14

91

すべての言語はC言語で書かれていますか?

言語は抽象的な数学のルールと制限(「私が書く場合のセットで、これをそれが起こります」)。本当に何も書かれていません。

通常、英語の形式化されたサブセット、数学表記、およびおそらくいくつかの特殊な仕様言語の混合で指定されます。構文は、EBNFまたはABNFのバリアントで指定されることがよくあります。

たとえばfor、ISO Ruby言語仕様の式の仕様は次のとおりです。

§11.5.2.3.4 for

構文

  • for-expression for for-variable [ここに行末 in 記号 はありません] expression do-clause end
  • for変数 左辺 | 複数左辺

意味論

以下のための式は次のように評価されます。

  1. 式を評価します。式の評価がbreak-expressionnext-expression、またはredo-expressionで終了した場合、動作は指定されていません。それ以外の場合はO、結果の値にしましょう。
  2. letをprimary-expression [no line-terminator here]という形式Eprimary-method-invocationとするblock-parameter-list block-bodyprimary-expressionの値は、block-parameter-listfor- variableブロック本体do-clauseの複合文です。 .each do | | endO

    評価するE; ただし、ブロック本体for式do節複合文であるブロックがこの評価中に呼び出される場合、ステップc)およびステップe)4)を除く§11.3.3のステップは、この呼び出しの評価に使用されます。

  3. のための式は、呼び出しの結果として得られる値です。

Scalaの型適合規則とは異なる例を次に示します。

多型型[a 1 >:L 1 <:U 1、…、a n >:L n <:U n ] Tは、多型型[a1>:L ′ 1 <:U′ 1、…、a n >:L ' n <:U' n ] T 'の場合、L' 1 <:a 1 <:U ' 1、…、L' n <:a n <:U'nT <:T ′およびL i <:L′ iおよびU ′ i<:U i for i∈{1、…、n}


C言語はすべての言語の母/父ですか?

いいえそうではありません。Cはかなり若いです。古い言語がたくさんあります。タイムトラベルは物理的に不可能なので、Cがこれらの古い言語に影響を与えることはまったく不可能です。

  • プランクカルル(1943)
  • スピードコーディング(1953)
  • Fortran(1954)
  • IPL(1956)
  • Lisp(1958)
  • アルゴル(1958)
  • COBOL(1959)
  • ジョヴィアル(1960)
  • APL(1962)
  • シムラ(1962)
  • SNOBOL(1962)
  • CPL(1963)
  • ベーシック(1964)
  • PL / I(1964)
  • RPG(1964)
  • BCPL(1966)
  • ISWIM(1966)
  • おたふく風邪(1967)
  • フォース(1968)
  • ロゴ(1968)
  • REFAL(1968)
  • B(1969)
  • ブリス(1970)
  • パスカル(1971)
  • KRL(1971)
  • Smalltalk(1972)

これらはすべて、Cが発明される前から存在していました。そして、他の多くの人は、Cが存在した後でも、Cの影響を持ちません。PASCALファミリーの言語(ALGOL-58、ALGOL-60、ALGOL-X、ALGOL-W、PASCAL、Modula-2、Oberon、Oberon-2、Active Oberon、Component Pascal)は完全に別の系統です。Lispファミリ全体(LISP、Franz Lisp、InterLisp、MacLisp、Scheme、Flavors、LOOPS、CommonLoops、Dylan、CommonLisp、Arc、Clojure、Racketなど)も無関係です。関数型言語(ISWIM、KRL、ミランダ、ML、SML、CAML、OCaml、F#、Haskell、Gofer、Clean)および依存型付けされたファミリ全体(Agda、Coq、GURU、Idris)は、Cから可能な限り離れています。同じことが、Smalltalkファミリー(Smalltalk、Self、Newspeak、Us、Korz)、ロジックプログラミングファミリー(PLANNER、Prolog、Mercury)、SQLなどにも当てはまります。

各コンセプト(OOPなど)はすべてC言語で実装されていますか?

オブジェクト指向の概念を備えた最初の言語はSimula(1960)とSmalltalk(1972)でしたが、オブジェクト指向システムは1953年までさかのぼって構築されていました(それらを呼び出すことはありません)。繰り返しますが、これはCが存在するずっと前のことなので、OOはCとは関係を持たない可能性があります。



2
@leftaroundabout:それは素晴らしいブログ投稿で、長年私のお気に入りの1つです。
ヨルグWミットタグ14

1
@FrancisDavey:ありがとう。リストをメモリからコンパイルし始め、Wikipediaで調べて覚えていない日付を追加しました。その後、ウィキペディアで言語のタイムラインを見つけ、そこからさらにいくつかの言語を選びました。BCPLの記事では1966年を引用していますが、タイムラインでは1967年を引用しているため、BCPLがすでに追加されていることに気づきませんでした。重複を削除します。
ヨルグWミットタグ14

1
あなたのリストでは、「htroF」は逆に綴られていませんか?
chux

2
「タイムトラベルは物理的に不可能です」—それは非常に論争の的です。もちろん、この回答の価値を損なうものではありません。
コンラッドルドルフ

50

多くの重要な言語の中核のほとんどはCで書かれていますが、状況は変化しています:

  • Python(CPython)の参照実装はCで記述されています(ただし、Jython / Java、PyPy / Python、IronPython / C#...など、他の言語で記述された実装もあります)
  • PHP Zend EngineはCで書かれています
  • Sun Microsystemsが開発した最初のJavaコンパイラはCで記述されていましたが、クラスライブラリは常にJavaで記述されています(Java VM自体を使用して実行するため)。JNI(Java Native Interface)を使用する特定のライブラリは、JVMの外部で使用することを目的としているため、他のさまざまな言語で部分的に記述されている場合があります。

    Sun / Oracle VMはC ++で記述されています。BEA / Weblogic / Oracle VMはCで記述されていますが、Java、Lisp、SmallTalk(IBM)で記述されたJVMがあります...

  • Perlは、PerlとCで記述されたモジュールの大規模なコレクションとともに、Cで記述れたコアインタープリターとして実装されます(ただし、Perg 6プログラミング言語のコンパイラーおよびインタープリターであるPugsはHaskellで記述されています)
  • MatzのRubyインタープリターまたはMRIと呼ばれることも多い公式のRubyインタープリターは、C記述され、独自のRuby固有の仮想マシンを使用します(ただし、Java仮想マシンで実行されるJava実装であるJRuby、C ++であるRubiniusがあります) LLVMを使用して実行時にマシンコードにコンパイルするバイトコード仮想マシン...)
  • Rの50%が Cで書かれている
  • そして、もちろん、CはCで書かれていた(だった)!(ただし、PDP-11を対象とした最初のCコンパイラは、Bとアセンブラの組み合わせでした)。

Cがしばしば選ばれた理由はたくさんあります:パフォーマンス、移植性、経験。

最後がおそらく最も重要なものです。Pythonは1991年に、PHPは1994/1995年に、Perlは1988年に、Rubyは1995年に開始されました。当時はJavaがリリースされたばかりで、C ++はまだ標準化されていません。


やや関連:


5
コンパイラ/インタープリターの実装の観点から見ると、Cはリファレンスポイントでした。さらに、多くの言語に直接的または間接的に影響を与えました(少なくとも構文的に)。
マンリオ14

2
すぐに、C#はC#で記述されたと言うことができます!(の種類)
DLeh

1
Monoの大部分(C#コンパイラと多く/ほとんどの.NET基本クラスライブラリを含む)はC#で記述されています。
チャーリーキリアン14

3
「Cはすべての言語の母/父ですか?」という質問に対する答え。「いいえ」なので、Cで書かれた多くの例を提供することは役に立たないと思います。反例は役立ちますが、選択はCから派生します。たとえば、Java、Pythonなどでも。現在は自己ホスト型であり、Cからブートストラップされているため、Cの「孫」のようなものです。LISP、FORTRAN、MLおよび(もちろん)マシンコードのような言語は、Cそれらの作成。
Warbo

2
もちろん、多くの言語の願望は、可能な限りそれ自体で実装されます。ただし、ほとんどの言語はCを呼び出す必要があるため、ほとんどの言語はCに依存しているようです。最新のオペレーティングシステムAPIと便利なライブラリの大部分は、Cバインディングを持つ傾向があります。また、「書かれた」という意味に注意する必要があります。通常、言語実装には複数の部分があります。少なくともコンパイラとランタイムシステムです。ランタイムシステムは、OSとのインターフェイスを改善するためにCで記述されることがよくあります。
仮名14

10

いいえ、一部の言語はCより前のものです。また、多くはCとは独立して実装されています。たとえば、http://en.wikipedia.org/wiki/Lisp_%28programming_language%29を参照してください


2
Javaには多くの実装があり、ほとんどはJavaで書かれています。Objective-CのGNU実装はC(またはC ++、最近変更されたと思われます)、LLVM実装はC ++で記述され、かつてはC#で記述されたインタープリターがありました。Pythonには多くの実装があり、1つはRPython、1つはJava、1つはC#、1つはCです。PHPには6つの主要な実装があります。Javaに2つ、C#に2つ、Cに1つ、C ++に1つです。
ヨルグWミットタグ14

1
いいえ。言語デザイナーは確かに他の言語の影響を受けますが、希望する場合はそれらの影響を無視することもできます。
ヨルグWミットタグ14

2
@FaizanRabbani言語は、本質的には、パラダイム、パターン、および妥協の概念と選択です。「言語は、他の言語から作成/適応されます」が、コンパイラの実装言語とはまったく関係ありません。言語Xは言語Yから派生させることができますが、Cまたは完全に別の何かで実装されます。この場合、「概念上の祖先」は重要ですが、コンパイラ言語は、時間とともに変化する可能性のある、ほとんど関係のない技術的なニュアンスです。
ペティス14

3
疑わしい価値がある場合、その最後のリンク-それを本当に真剣に受け止めるにはあまりにも多くの間違い。
不明なコーダー14

4
@SebastianGodelet:HotSpotはJava言語の実装ではありません。JVMバイトコード言語の実装です。これらは、まったく異なる2つの言語です。Java言語の最も広く使用されている実装は、javacMartin Odersky(Scalaの名声)が100%Javaで記述したOracle JDK / OpenJDK、100%Java(IBMのJikesコンパイラーから派生)で記述されたEclipseコンパイラー、Jikesおよび100%Javaから派生したIBMのJ9。私の知る限り、Javaで書かれていない、やや広く使用されている唯一のJavaコンパイラはGCJです。
Mittag 14

4

できればこれをコメントにしますが、できません。

Cが広く普及している理由の1つは、Cが開発された最も初期の言語の1つであり、膨大な量の現代言語がその構造(Java、Go、PHP、Perlなど)に基づいているためである-それがそれ以上の場所。

忘れられがちなもう1つの理由は、1973年にUnixがCで書き直され、Unixのシステムコールの多くがCプログラム/関数としても利用できるため、2つのリンクが高度にリンクされたことです。Unixは全体として現代のプログラミングの開発の強力な部分だったので、Cはそれに悪名をintoせました。

すべてを言ったが、あなたの質問への答えは「いいえ」です。CはALGOLと呼ばれる言語に基づいており、ALGOL(FORTRAN、Lisp、COBOL)とC(誰も思いつかない)の両方の多くの競合がありました。おそらくプログラミング設計における最大のパラダイムシフトであるオブジェクト指向プログラミングは、C ++が非常に人気のあるOOP言語であるにもかかわらず、Cに由来するものではありません(最初にLispまたはSimula 67で登場しました)。OOPが登場する頃には、Cは非常に人気のある言語であったため、最初にする必要はありませんでした。主にその強力なメモリ制御機能(構造体が作成するメモリを直接割り当てたり割り当て解除したりできる)により、現在も使用され続けています。厳しいメモリバジェットでプログラムを作成できるようにし(ビデオゲームを考えてください)、高度に最適化されたコンパイラ(明らかにコンパイラに依存します)。確かに、Java JITのコンパイルと言語内のメモリマネージャがより高度になるにつれて、これらの機能でさえ地歩を失っています。


1
これは作られたポイントを超える大幅な何かを提供しているようだし、特に中に、前の回答で説明していないトップ1「CはALGOLと呼ばれる言語をベースにしています」という疑問文に対する除き、
GNAT

4
ALGOLにおけるCの根拠はほとんど疑問がある...参照してくださいcm.bell-labs.com/who/dmr/chist.htmlen.wikipedia.org/wiki/C_%28programming_language%29
WannabeCoder

実際の話ははるかに複雑で面白いそれよりもあります。私は物事がここにレイアウトされている方法は、読者のためにほとんど有用であると言うだろう
ブヨ

3

明らかにそうではありません。Cが以前に存在しなかった場合、最初のCコンパイラはどのようにCで作成できますか?これは鶏と卵の問題ではありません。

ブートストラップと呼ばれる言語の最初のコンパイラを書く方法はたくさんあります

さらに、ほとんどのコンパイラは、主に言語とコンパイラ自体を促進するために、セルフホスティングを達成しようとするか、それ自体をその言語にコンパイルしようとします


12
最初のOberonコンパイラー Oberon 作成れました。あなたが教授であり、あなたのためにコンパイラを手で翻訳する学生がたくさんいるなら、それはまったく問題ありません(Wirth教授が持っていました)。
ヨルグWミットタグ14

@Jorgこの質問はC程度で、何のCコンパイラは、そのように書かれていなかったので、私はあることを書いて気にしない上にリンクされ、ブートストラップ資料に記載されたもの
phuclv

14
@JörgWMittag-最初の自動化された OberonコンパイラはOberonで作成されました。実際の最初の Oberonコンパイラはたくさんの学生でした。
nnnnnn 14

4
@nnnnnn:私はこの「学生の集まり」をコンパイラではなくインタプリタと考えています。
パウロEbermann

4
@PaŭloEbermann別の人間の要素を追加すると、「コンピューター」は元々役職でした。
chux

2

以下に、Cで書かれていないプログラミング言語のリストと、それら実装されている言語を示します

  • ハスケル-ハスケル
  • イドリス-ハスケル
  • Adga-ハスケル
  • クラッシュ-ハスケル
  • PureScript-Haskell
  • エルム-ハスケル
  • 水銀-水銀
  • Rust-Rust(最初はOCaml)
  • 行く-行く
  • クリスタル-クリスタル
  • OCaml-OCaml
  • Frege-Frege + Java
  • Haxe-OCaml + Haxe
  • スカラ-スカラ
  • フサルク-ハスケル
  • ATS-ATS

コンパイラを実装するのに最適な言語は、おそらくCからかなり遠くなるでしょう。関数型言語は、再帰スキームやモナドパーサコンビネータ(タイプクラスがある場合)などを提供するため、コンパイラの動作に特に適しています。

第二に、Cが「すべてのプログラミング言語の母/父」であるかどうかについての質問に対処するためです。Cは登場当時はよく設計された言語であり、言語設計者に影響を与えたのは間違いないでしょう。しかし、結局のところ、Haskellは基本的にあらゆる方法でCを離れます。Cは45歳であり、その間に私たちがより良いことを学んだことは驚くことではありません。

最後に、3番目の質問に答えるのは、Cが「すべての概念」を実装しているということだけではありません。特に、Cで関数型プログラミング(メタモーフィズム、または不可解なシンクロモーフィズムなど)から高度な概念の一部を実装しようとすることは、非常に困難です。私はオブジェクト指向プログラミングに特に精通しているわけではありませんが、一部のオブジェクト指向言語には合計型があるという事実を知っています。


Cは決して「信じられないほどうまく設計された言語」ではありませんでした。今日私たちが目にするいぼは、最初からいぼであることが知られていました。しかし、それは開発者に優しいUnixオペレーティングシステムのネイティブ言語で十分であり、Bell LabsがUnixを大学に押し出した後、C / Unixは世代のコンピュータープロフェッショナルのお気に入りの言語/ OSになりました。
ソロモンスロー

PS。、Cには多くの独創的なアイデアはありませんでした。すべてのブロック構造の手続き型プログラミング言語の母/父を探しているなら、ALGOLを見てみたいかもしれません。
ソロモンスロー

LispマクロはCよりもはるかに優れており、ALGOLとSmalltalkには、コードの整理に役立つブロック、クロージャー、ネストされた関数がありました。実際、Lispはアセンブラーのマクロプロセッサとして使用でき、Cがポリモーフィズムよりも前に登場した初期のC. Simulaよりも短くて高速なコード(S式のカスタム処理)を作成できました。Lisp、APL、およびSmalltalkには、解釈およびコンパイルされたコードをインターリーブできるUnixの「sh」と「C」とは異なり、完全に機能する(シェルとプログラム間の同じコード)「シェル」がありました。Lisp(rplaca / rplacd)ではポインターが簡単でした。
aoeu256

Cの最大の利点は、Cの「コンパイラ」を作成するのが簡単だったため、ウイルスのように簡単に拡散できることでした。また、Cのおかげで、現代のプログラマはプログラムをモジュール化する方法を知らない(可変性はモジュール性を損ないます)、副詞/コンビネータ/高階関数の概念がありません(毎回ループを手動で記述します)。後方互換性のためにCコードを実行するCPU。
aoeu256

1

プログラミング言語は、通常は英語の文書で書かれた仕様です(ソフトウェアではありません!構文の大部分はEBNFなどの形式で記述されています。場合によっては、そのセマンティクスも部分的に形式化されます)。

たとえば、C11はn1570で定義されています(これを読む必要があります)。Schemeの方言のいくつかはR5RSで定義されています(これも読む必要があり、非常によく書かれています)。

プログラミング言語は、一部のソフトウェアによって実装される場合があります。そのソフトウェアは、プログラミング言語自体で書かれたコンパイラである場合があります。ブートストラップコンパイラについて読んでください。

コンパイルされたプログラミング言語自体でコンパイラを作成できます。その言語XXが真新しい場合、他の実装言語(おそらくC)でその言語のサブセットの最小限のインタープリターまたはコンパイラーを作成することを含む一時的なステップを実行する必要があります。インタプリタ(他のコンパイラをコンパイルするのに十分であるために「良い」必要はありません)。XXで書かれたXXコンパイラをコンパイルしたら、一時的なコンパイラを捨てることができます。

多くの場合(常にではありませんが)、ランタイムシステムの一部はC(特にガベージコレクター)で記述されています

bonesは、それ自体が完全に記述されたSchemeコンパイラおよびランタイムであることに注意してください(そして、完全にブートストラップされた実装の他の多くの例を見つけることができます)。

ところで、コンパイラのターゲット言語としてCを使用すると便利です。

今日、多くのプログラミング言語の実装はフリーソフトウェアまたはオープンソースです。ソースコードを自由に勉強してください(そしておそらく貢献してください)!

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