時々、異なる言語(C / C ++、C#)でプログラミングしているときに、この考えが思い浮かびます。
- すべての言語はCプログラミング言語で書かれていますか?
- C言語はすべての言語の母/父ですか?
- 各コンセプト(OOPなど)はすべてCで実装されていますか?
私は正しい方向にいますか?
時々、異なる言語(C / C ++、C#)でプログラミングしているときに、この考えが思い浮かびます。
私は正しい方向にいますか?
回答:
番号。
OCaml、Haskell、SchemeのようなLisp方言、および他のいくつかの言語は、趣味言語の開発によく使用されます。
ユビキタス言語であるため、多くの言語がCで実装されており、レクサーパーサージェネレーター(yaccやbisonなど)などのコンパイラー作成ツールは十分に理解されており、ほぼユビキタスです。
しかし、C自体は、Cが最初に作成されたときには、Cで開発することはできませんでした。実際には、もともとはB言語を使用して開発されました。以前の言語(Fortranなど)は通常、ネイティブアセンブリ言語またはCが存在するずっと前にマシンコードを使用してブートストラップされていました。
無関係に、 OOPのような言語パラダイムは一般に言語に依存しません。たとえば、関数型パラダイムは、プログラミング言語が存在するずっと前に数学の基盤として開発されました(Alonzo Churchによって)。手続き型および構造化プログラミングのパラダイムは、ジョン・フォン・ノイマンのような理論家の数学的研究から生まれました。オブジェクト指向は、いくつかの異なる無関係な努力によって開発されました。一部はラムダ計算(機能的パラダイム)から、一部はAlan KayによるXerox PARCのSmallTalkのような動的プログラミングシステムからです。
Cは、これらのアイデアが生まれてから数十年後の物語のほんの一部です。
すべての言語はC言語で書かれていますか?
言語は抽象的な数学のルールと制限(「私が書く場合のセットで、これを、それが起こります」)。本当に何も書かれていません。
通常、英語の形式化されたサブセット、数学表記、およびおそらくいくつかの特殊な仕様言語の混合で指定されます。構文は、EBNFまたはABNFのバリアントで指定されることがよくあります。
たとえばfor
、ISO Ruby言語仕様の式の仕様は次のとおりです。
§11.5.2.3.4
for
式構文
- for-expression → for for-variable [ここに行末 in 記号 はありません] expression do-clause end
- for変数 → 左辺
|
複数左辺意味論
以下のための式は次のように評価されます。
- 式を評価します。式の評価がbreak-expression、next-expression、またはredo-expressionで終了した場合、動作は指定されていません。それ以外の場合は
O
、結果の値にしましょう。letをprimary-expression [no line-terminator here]という形式
E
のprimary-method-invocationとするblock-parameter-list block-body、primary-expressionの値は、block-parameter-listはfor- variable、ブロック本体はdo-clauseの複合文です。 .each do | | endO
評価する
E
; ただし、ブロック本体がfor式のdo節の複合文であるブロックがこの評価中に呼び出される場合、ステップc)およびステップe)4)を除く§11.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'nはT <:T ′およびL i <:L′ iおよびU ′ i<:U i for i∈{1、…、n}。
C言語はすべての言語の母/父ですか?
いいえそうではありません。Cはかなり若いです。古い言語がたくさんあります。タイムトラベルは物理的に不可能なので、Cがこれらの古い言語に影響を与えることはまったく不可能です。
これらはすべて、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とは関係を持たない可能性があります。
多くの重要な言語の中核のほとんどは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があります...
Cがしばしば選ばれた理由はたくさんあります:パフォーマンス、移植性、経験。
最後がおそらく最も重要なものです。Pythonは1991年に、PHPは1994/1995年に、Perlは1988年に、Rubyは1995年に開始されました。当時はJavaがリリースされたばかりで、C ++はまだ標準化されていません。
やや関連:
いいえ、一部の言語はCより前のものです。また、多くはCとは独立して実装されています。たとえば、http://en.wikipedia.org/wiki/Lisp_%28programming_language%29を参照してください。
javac
Martin Odersky(Scalaの名声)が100%Javaで記述したOracle JDK / OpenJDK、100%Java(IBMのJikesコンパイラーから派生)で記述されたEclipseコンパイラー、Jikesおよび100%Javaから派生したIBMのJ9。私の知る限り、Javaで書かれていない、やや広く使用されている唯一のJavaコンパイラはGCJです。
できればこれをコメントにしますが、できません。
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のコンパイルと言語内のメモリマネージャがより高度になるにつれて、これらの機能でさえ地歩を失っています。
明らかにそうではありません。Cが以前に存在しなかった場合、最初のCコンパイラはどのようにCで作成できますか?これは鶏と卵の問題ではありません。
ブートストラップと呼ばれる言語の最初のコンパイラを書く方法はたくさんあります
さらに、ほとんどのコンパイラは、主に言語とコンパイラ自体を促進するために、セルフホスティングを達成しようとするか、それ自体をその言語にコンパイルしようとします
以下に、Cで書かれていないプログラミング言語のリストと、それらが実装されている言語を示します。
コンパイラを実装するのに最適な言語は、おそらくCからかなり遠くなるでしょう。関数型言語は、再帰スキームやモナドパーサコンビネータ(タイプクラスがある場合)などを提供するため、コンパイラの動作に特に適しています。
第二に、Cが「すべてのプログラミング言語の母/父」であるかどうかについての質問に対処するためです。Cは登場当時はよく設計された言語であり、言語設計者に影響を与えたのは間違いないでしょう。しかし、結局のところ、Haskellは基本的にあらゆる方法でCを離れます。Cは45歳であり、その間に私たちがより良いことを学んだことは驚くことではありません。
最後に、3番目の質問に答えるのは、Cが「すべての概念」を実装しているということだけではありません。特に、Cで関数型プログラミング(メタモーフィズム、または不可解なシンクロモーフィズムなど)から高度な概念の一部を実装しようとすることは、非常に困難です。私はオブジェクト指向プログラミングに特に精通しているわけではありませんが、一部のオブジェクト指向言語には合計型があるという事実を知っています。
プログラミング言語は、通常は英語の文書で書かれた仕様です(ソフトウェアではありません!構文の大部分はEBNFなどの形式で記述されています。場合によっては、そのセマンティクスも部分的に形式化されます)。
たとえば、C11はn1570で定義されています(これを読む必要があります)。Schemeの方言のいくつかはR5RSで定義されています(これも読む必要があり、非常によく書かれています)。
プログラミング言語は、一部のソフトウェアによって実装される場合があります。そのソフトウェアは、プログラミング言語自体で書かれたコンパイラである場合があります。ブートストラップコンパイラについて読んでください。
コンパイルされたプログラミング言語自体でコンパイラを作成できます。その言語XXが真新しい場合、他の実装言語(おそらくC)でその言語のサブセットの最小限のインタープリターまたはコンパイラーを作成することを含む一時的なステップを実行する必要があります。インタプリタ(他のコンパイラをコンパイルするのに十分であるために「良い」必要はありません)。XXで書かれたXXコンパイラをコンパイルしたら、一時的なコンパイラを捨てることができます。
多くの場合(常にではありませんが)、ランタイムシステムの一部はC(特にガベージコレクター)で記述されています。
bonesは、それ自体が完全に記述されたSchemeコンパイラおよびランタイムであることに注意してください(そして、完全にブートストラップされた実装の他の多くの例を見つけることができます)。
ところで、コンパイラのターゲット言語としてCを使用すると便利です。
今日、多くのプログラミング言語の実装はフリーソフトウェアまたはオープンソースです。ソースコードを自由に勉強してください(そしておそらく貢献してください)!