ときどき、異なる言語(C/C++、C#)でプログラミングしているときに、この考えが思い浮かびます。
私は正しい方向にいますか?
番号。
OCaml、Haskell、SchemeのようなLISP方言、およびその他のいくつかの言語は、趣味言語の開発でよく使用されます。
ユビキタス言語であるため、多くの言語がCで実装されています。また、lexer-parserジェネレーター(yaccやbisonなど)などのコンパイラー作成ツールはよく理解されており、ほとんどどこにでもあります。
しかし、C自体は、最初に作成されたときは、もともとCで開発できませんでした。実際、元々は[〜#〜] b [〜#〜]言語を使用して開発されました。以前の言語(Fortranなど)は、通常bootstrappedであり、Cが存在するずっと以前から、ネイティブアセンブリ言語またはマシンコードを使用していました。
無関係に、OOPのような言語パラダイムは一般にlanguage-agnostic。たとえば、関数型パラダイムは、プログラミング言語が存在するずっと前に、数学の基礎として(Alonzo Churchによって)開発されました。手続き型および構造型プログラミングパラダイムは、Johnのような理論家の数学的研究から生まれましたフォンノイマン。オブジェクト指向は、いくつかの異なる、無関係な取り組みによって開発され、ラムダ計算(機能パラダイム)から一部、動的プログラミングから一部開発されましたXerox PARCのSmalltalkなどのシステム。
Cは、これらのアイデアが生まれた後の物語のほんの一部ですdecades。
すべての言語はC言語で書かれていますか?
言語は、抽象的な数学的なルールと制限のセットです(「私がthisと書いた場合、thatが発生した場合」)。本当に何も書かれていません。
それは通常、英語の正式なサブセット、数学表記、およびおそらくいくつかの特殊な仕様言語の混合で指定されます。構文は多くの場合、 [〜#〜] ebnf [〜#〜] または [〜#〜] abnf [〜#〜] のバリアントで指定されます。
たとえば、以下はISOのfor
式の仕様ですRuby言語仕様:
§11.5.2.3.4
for
式構文
- for-expression→ for for-variable[ここには行末記号はありません] in expressiondo-clause end
- for-variable→左側
|
複数の左側意味論
for-expressionは次のように評価されます。
- expressionを評価します。式の評価がbreak-expression、next-expression、またはredo-expressionで終了する場合、動作は指定されていません。それ以外の場合は、
O
を結果の値とします。
E
をprimary-method-invocationの形式でprimary-expression[no line-terminator here].each do | block-parameter-list | ブロック本体 end、ここでprimary-expressionの値はO
であり、block-parameter-listはfor-variableであり、block-bodyは、do-clauseのcompound-statementです。評価
E
;ただし、block-bodyがdo-clauseのfor-clauseのfor-expressionであるブロックが呼び出された場合、この評価の間、§11.3.3のステップ(c)とe)4)を除いて、この呼び出しの評価が行われます。for-expressionの値は、呼び出しの結果の値です。
Scalaの型適合ルールとは異なる例を次に示します。
多相型[a1 >:L1 <:U1 、…、aん >:Lん <:Uん] Tは多相型[a1>:L 'に準拠しています1 <:U ′1 、…、aん >:L ′ん <:U ′ん] T 'ifL'の場合1 <:a1 <:U ′1 、…、L ′ん <:aん <:U′n1つはT <:T ′およびL私 <:L ′私およびU '私 <:U私fori∈{1、…、n}。
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言語で実装されていますか?
OOの概念を持つ最初の言語は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
できればこれをコメントにしますが、コメントはできません。
Cが非常にユビキタスであると思われる理由の1つは、Cが開発された最も初期の言語の1つであり、膨大な量の最新の言語がその構造(Java、Go、PHP、Perlなど)に基づいているためです。それ以上の場所。
よく忘れられるもう1つの理由は、1973年にUnixがCで書き直され、UnixのシステムコールのmanyがCのプログラム/関数としても使用できるようになり、2つが高度に相互リンクされたことです。 Unixは全体として現代のプログラミングの開発の強力な部分だったので、Cはそれに夢中になりました。
すべてを言ったとしても、あなたの質問に対する答えは「いいえ」です。 CはALGOLと呼ばれる言語に基づいており、ALGOL(FORTRAN、LISP、COBOL)とC(どれも頭に浮かばない)の両方で多くの競合他社がありました。 C++が非常に人気のあるOOP言語であるにもかかわらず、オブジェクト指向プログラミングは、おそらくプログラミング設計における最大のパラダイムシフトであるCに由来しませんでした(LISPまたはSimula 67で最初に登場しました。尋ねる)。 OOPが登場する頃には、Cは非常に人気のある言語でしたので、最初にする必要はありませんでした。C++の "拡張"は、いわば主要なOOP言語も。それは主に、強力なメモリ制御機能(構造体が作成するメモリを直接割り当てたり割り当て解除したりできる)が原因で現在も使用されており、厳しいメモリバジェット(ビデオゲームを考える)と高度に最適化されたコンパイラ(明らかにコンパイラ)。確かに、Java JITコンパイルと言語内メモリマネージャがより高度になるにつれて、これらの機能でさえ地盤を失っています。
明らかにそうではありません。 Cが以前に存在しなかった場合、最初のCコンパイラはどのようにしてCで作成できますか?これは鶏と卵の問題ではありません。
bootstrapping と呼ばれる言語の最初のコンパイラを書く方法はたくさんあります。
さらに、ほとんどのコンパイラーは self-hosting を達成しようとするか、それ自体をその言語でコンパイルし、主に言語とコンパイラー自体を宣伝します
以下は、Cで記述されていないプログラミング言語と、それらが実装されている言語が実装されている言語のリストです。
コンパイラーの実装に最適な言語は、おそらくCからかなり遠く離れています。関数型言語は、再帰スキームやモナディックパーサーコンビネーター(型クラスがある場合)などを提供するため、コンパイラーの作業に特に適しています。
第二に、Cが「すべてのプログラミング言語の母/父」であるかどうかについての質問に対処するため-実際にはそうではありません。 Cは、登場した当時はよく設計された言語でしたが、それが言語デザイナーに影響を与え、その後非常に異なることを行ったのは間違いありません。しかし結局のところ、Haskellは基本的に可能な限りあらゆる方法でCを離れます。 Cは45歳で、その間に私たちがより上手になることを学んだのは当然のことです。
最後に、3番目の質問に答えるなら、Cが「すべての概念」を実装するのは単純には当てはまりません。特に、Cで関数型プログラミングから高度な概念(変成作用、または禁じられたシンクロモーフィズムなど)を実装しようとすると、途方もなく困難になります。私はオブジェクト指向プログラミングに特に精通していませんが、一部のオブジェクト指向言語には合計型があることは知っています。
プログラミング言語は仕様です(ソフトウェアではありません!)通常、英語のドキュメントで記述されます(例: [〜#〜] ebnf [ 〜#〜] ほとんどの構文で、時には semantics も部分的に形式化されます)。
たとえば、C11は n157 で定義されています(これをお読みください)。 Schemeの一部の方言は R5RS で定義されています(これも読む必要があります。非常によく書かれています)。
プログラミング言語は、一部のソフトウェアによって実装されている場合があります。時々、そのソフトウェアはプログラミング言語自体で書かれたコンパイラーです。 ブートストラップコンパイラ について読んでください。
コンパイラは、コンパイルされたプログラミング言語自体で記述できます。その言語XXがまったく新しい場合は、その言語のサブセットの最小限のインタープリターまたはコンパイラーを他の実装言語(おそらくC)で書くことを含む一時的なステップを経る必要があり、後でその一時的なコンパイラーまたはインタプリタ(他のコンパイラをコンパイルするのに十分であるために、「良い」である必要はありません)。 XXで書かれたXXコンパイラーをコンパイルしたら、一時的なコンパイラーを破棄できます。
多くの場合(ただし常にではありません) ランタイムシステム は一部Cで記述されています(特に ガベージコレクター )。
bones は、Schemeコンパイラとランタイム自体が完全に記述されていることに注意してください(完全にブートストラップされた実装の他の多くの例を見つけることができます)。
ところで、Cを コンパイラのターゲット言語 として使用すると便利です。
今日、多くのプログラミング言語の実装は フリーソフトウェア または オープンソース です。彼らのソースコードを自由に研究して(そしておそらく貢献して)ください!