ScalaがCまたはC ++で実装されなかった理由


28

ScalaがCやC ++ではなくJavaと.NETで実装された理由を知っている人はいますか?ほとんどの言語はCor C ++で実装されています(つまり、Erlang、Python、PHP、Ruby、Perl)。Javaおよび.NETライブラリにアクセスできること以外に、Javaおよび.NETで実装されたScalaの利点は何ですか?

更新

Scalaは、Cで実装された場合、JVMに依存するよりもより適切に調整できるため、より多くの利益を得られませんか?


18
また、既存のJavaライブラリを使用し、Javaコードと緊密に相互運用できることは大きな利点であり、小さなことではありません。
タマスシェレイ

6
@OP:JVM(または、その点でCLR)の上に言語を実装するのは良くないように話します。Cで可能なチューニングは、CLRまたはJVMに加えられたチューニングの量に近いものではありません。プラットフォームが改善されると、言語は自動的に無料で取得します。選択を考えると、誰もgood'ol Cの上に彼らの言語を実装するべきではありません。
ちー

8
@Chii、ちょうどJavaはCよりもまだ遅い、それを認める
ジョシュアPartogi

19
@ jpartogi、JavaはCより遅くも速くもできません。これらは両方の言語であり、種牡馬ではありません。特定の状況では、Javaコンパイラーによってコンパイルされ、特定のJVMで実行される特定のコードは、Cコンパイラーによって生成されるほぼ同等のコードよりも低速です。他のいくつかの条件では、後者のほうが遅くなります。
SKロジック

4
Scalaのランタイム環境はC ++プログラムです。JVM。
mike30

回答:


59

CとC ++は言語であり、JVMは仮想マシンであり、.Netはプラットフォームであるため、問題は混乱を招きます。ScalaはCまたはC ++で実装でき、仮想マシンのバイトコードの代わりにマシンコードを生成できます。

尋ねられた質問に答える:

Scalaは実際に実装されている言語であるScalaの方がはるかに優れているため、CまたはC ++で実装されていません。

なぜそれが良いのですか?さて、Scala言語に対するOderskyの目標について読んでください。

意図された可能性のある質問への回答:

Scalaは主にJVMバイトコードを生成します。これは、信頼性が高く効率的なガベージコレクター、実行時最適化、JVMによるジャストインタイムコンパイルなどの機能に加えて、優れた移植性を提供するためです。

最後に繰り返しますが、JVM は、実行中のコードのホットコードをマシンコードにコンパイルします。これは、CおよびC ++コンパイラーと同じようにコンパイルします。

他にも利用可能な仮想マシンがありますが、Scalaの作成者であるOderskyはすでにJVMに精通しています。彼は代替手段としてCLRを使用するつもりでしたが、それを実現するための努力はまだ成功していません。

尋ねられる可能性がある/されるべき質問に答える:

マシンコードにコンパイルしても、JVMバイトコードにコンパイルするよりも十分な利点はありません。

JVMに相当するものに勝るマイクロベンチマークをCまたはC ++で生成することは確かに可能です。CまたはC ++の非常に最適化されたコードが、JavaまたはScalaの非常に最適化されたコードに勝ることも事実です。ただし、実行時間の長いプログラムの場合、違いはそれほど大きくありません。

Scalaは、実行時間の短いプログラムのオーバーヘッドが大きすぎるため、特に優れたスクリプト言語ではないことに注意してください。

ただし、ほとんどの場合、実行速度よりも開発速度と保守の容易さが重要です。簡単に理解して変更できる非常に高レベルのコードを書くことに人々が関心を持っている場合、JVMが提供する実行時最適化は、CまたはC ++コンパイラーによるコンパイル時最適化を簡単に打ち負かし、JVM(およびCLR )実際に高速に実行されるターゲット。

したがって、Scala コンパイラがマシンコード実行可能プログラムであるか、Scala プログラムがマシンコードであるかどうかに関係なく、潜在的な速度向上は必ずしも実際の速度向上に変換されません。

ところで、

反例として、Haskellを紹介します。Haskellはマシンコードを生成しますが、HaskellプログラムはDebianの銃撃戦ではScalaのそれよりも劣っています。それを考えると、マシンコードに直接コンパイルされた場合、Scalaプログラムがより高速になると確信できる人はいますか?


3
@ mike30 Scalaは、C ++で作成されていなくても、どのJVMでも実行されるため、その引数は保持されません。また、実行時には、C ++コードはなく、マシンコードのみです。ただし、このコメントの内容はわかりません。
ダニエルC.ソブラル

3
本当のポイントは、マシンコードの生成はバイトコードの生成よりもはるかに複雑であり、すべてのOSに特定の実装が必要であるだけでなく、CPUおよび異なるアーキテクチャ(ARM、x86、x86_64)および高度な命令(MMX、SSE ...)。このようにして、JVMにこの側面が委任されます。
ラファエロ

2
実行パフォーマンスについて多くを語るのであれば、なぜメモリパフォーマンスについて語らないのですか?あなたは物事があなたが想像するほど良くないかもしれないことを恐れていますか?
luke1985

3
@ lukasz1985パフォーマンスは向上しますが、パフォーマンスの説明ではそれが取り上げられているため、その点では無関係です。残っているのは、アプリケーションがどれだけのメモリを使用するかを気にするかどうかであり、GCとそれの間を選択する必要があります。Scalaによって占有されていない非常に特定の開発スペースを除き、毎回GCを選択します。そして、「誰にも言えない」というのはでたらめです。誰もがその権利を持っています。また、C / C ++はレガシーのため非常に関連性がありますが、過去5年間にリリースされていたとしても人気がありません。
ダニエルC.ソブラル

3
@ lukasz1985私が理解していないというあなたの唯一の証拠は、私があなたに同意しないということです。それに対する別の説明は、あなたが間違っているということです。そして、誰かが生きていて「それから」プログラミングしているので、現代の選択肢よりもCとC ++を選ぶことに関わる意思決定について、最初の視点を持っています。機械語との類似性とは異なり、話し言葉との関連性はまったくありません。
ダニエルC.ソブラル

31

世界全体に導入されたときに言語が直面する大きなハードルの1つは、ライブラリの可用性です。これに対する従来の対応は、Cベースのライブラリへのアクセスを許可するCベースのFFI(外部関数インターフェイス)を提供することでした。これはさまざまな理由から理想的ではありませんが、その主なものは次のとおりです。

  • 多くの高レベル言語と互換性のない、ライブラリがやり取りしたいさまざまな方法があります。ライブラリはへのポインタを望んでいる場合たとえばstruct、どのなしのポインタを持つ言語ですノー structsが対処しますか?
  • さまざまなライブラリと言語のメモリモデルの間には厳しい相互作用があり、多くの場合、解決できないか、解決できる場合はエラーやバグが発生しやすくなります。
  • 多くのFFIのグルーコードは重要であり、実際には普遍的ではない知識を前提としています。(信じられないかもしれませんが、すべてのプログラマーがCの達人であるわけではありません。

これは、C ++ではさらに悪化します。C ++は、他の言語ではなく、同じプラットフォーム(!)上のコンパイラからC ++(バイナリレベル)との互換性さえありません。

JVMをターゲットにすると、これらの問題の多くが解決されると同時に、Javaベースのライブラリの非常に膨大なスイートにアクセスできるようになります。(どれだけ巨大なのでしょうか。ApacheSoftware Foundationのスターター向けの膨大なセレクションをご覧ください。)

  • Javaの呼び出し規則と所有権の規則は、Cの規則よりも規則的です。
  • JVMは、インターフェースとなる言語とライブラリの両方に対して単一メモリモデル(ガベージコレクションを含む)も提供します。誰が何を所有し、誰がどこをクリーンアップする必要があるかを追跡する必要はありません。ランタイムが自動的に実行します。
  • JVMで構築されたほとんどの言語のFFIのグルーコードは存在しません(言語の裏でフレームワークとして提供されているように)。たとえば、Scala、Clojure、JR​​ubyなどのJavaライブラリにアクセスするために、Javaでプログラミングする必要はありません。ネイティブの「オブジェクト」にアクセスするのと同じ方法でJavaオブジェクトにアクセスします(例えば、ClojureはOOPの意味での実際のオブジェクトを持っている)とあなたの母国語で。

これらの利点に加えて、Java 再コンパイルせずに実行する任意の場所で実行するという追加の利点もあります(ただしテスト行う必要があります:1回書き込み、どこでもテストする)。

CLRは同様の長所を提供しますが、IMOの弱点を追加します。これは、ほとんどベンダーロックイン環境です。(はい、私はMonoについて知っています。それはまだベンダーロックイン環境だと思います。)


3
C#とCLRは実際には、誰でも使用できるオープンスタンダードであることを理解しています。
エリン

7
私が「Monoについて知っている」場所についてのビットと、「それはまだベンダーのロックイン環境だと思う」についての少しのヒントがそこにあると思います、Erin。
ちょうど私の正しい意見

3
@Erinはすべての.NET Frameworkがそうであるわけではありません
代替案

1
@alternative:それがあまりにもロックインされている場合、Java適合性テストはまだ無料ではなく、せいぜい6の1つ、Javaの他の6分の1であると考えてください。
デュプリケータ

18

このインタビューによると、既存のJavaインフラストラクチャとライブラリへのアクセスが主な理由でした。

... Javaは、非常に厳しい制約を持つ既存の言語です。その結果、私は彼らがやりたかった方法で多くのことを行うことができませんでした。私が確信していた方法は、それらを行う正しい方法だと思います。そのため、基本的に私の仕事の焦点がJavaを改善することであったとき、その後、一歩後退する時だと判断しました。きれいなシートから始めて、Javaよりも優れたものを設計できるかどうかを確認したかったのです。しかし同時に、ゼロから始められないことも知っていました。既存のインフラストラクチャに接続する必要がありました。それ以外の場合、ライブラリ、ツールなどを使用せずに何もしないで自分をブートストラップすることは現実的ではありません。

そのため、Javaとは異なる言語を設計したいにもかかわらず、常にJavaインフラストラクチャ(JVMとそのライブラリ)に接続することにしました。それがアイデアでした...


10

あなたが言及する他のすべての言語、Erlang、Python、PHP、Ruby、Perl-これらはすべてJavaと.NETの前に作成されました。これらの言語の作成者がその時点でJavaまたは.NETランタイム環境を使用できる場合、言語を構築するときにそれらを利用した可能性があります。

もちろん、私は私が言うことができないので、これらの言語の開発者のために話すことができないことを確認するためにそれらを構築するとき、彼らは、.NETおよび/またはJavaを使用していたであろうと、彼らが利用されていたが、それは、Aのように私には思えます良いアイデア。結局、Java / .NETバイトコードにコンパイルするように言語を設計することにより、JITコンパイラー/オプティマイザーのすべての利点が得られ、Java / .NETが実行されているすべてのプラットフォームで言語が自動的に実行され、 Java / .NETライブラリなど。


2
説明されている利点は、たとえばPythonがJVM(Jython)と.NET(IronPython)の両方で再実装された理由の一部です。
dancek

2
-1:新しい言語が利用可能であるため、特定のプラットフォーム(.NetまたはJVM)に依存している可能性があると仮定すると、私にとっては良い議論のようには見えません。たとえば、PythonやErlangがそのようなプラットフォームで実行される正当な理由は見当たりません。歴史はそれをすべて言っているのではありません。
クライム

1
また、PHPでさえ、JVMまたは.Netを介して行うことはできません。@Dean Harding> IronPythonやJythonが価値のあるものを証明したとは思いません。
クライム

1
申し訳ありませんが、明確ではありませんでした。つまり、JVMまたは.Netでの作業は多くの開発者を悩ませる多くのことを意味するため、「成功」(PHPまたはPython)がなければ意味がありません。現在よりもニッチな言語です。技術的な面では、プラットフォーム(.NetまたはJVM)は、言語を構築する方法を推進するため、問題になります。マシンで述べることは、希望する言語を正確に作成する方法です。そのため、JVMを使用できるかどうかにかかわらず、.NetおよびJVMを介してビルドする正当な理由はありません。迅速な実装以外。
クライム

2
小さな修正:JavaはPHPよりも古いです。しかし、PHPはCGIプログラムとして始まり、後にApache httpdモジュールになり、大きくなりました。両方(cgiとhttpdモジュール)は、Javaではうまく機能しません。したがって、物事はそれほど簡単ではありません。JVMはすべてのプラットフォームではありません。;-)
ヨハネス

6

Cコードは、ネイティブコード(マシンコード)に静的にコンパイルされます。

Scalaは静的にjavaバイトコードにコンパイルされ、必要に応じて、最適化されたネイティブコードに動的にコンパイルされます。プロセス:

Scalaコード ---静的にコンパイル---> JVMバイトコード ---動的にコンパイル-JVM-Hotspot-to ----> ネイティブコード

任意の言語を構築/実行するための一般的なオプション:

  • a)ランタイムインタープリターエンジンを介してソースコードを直接解釈する
  • b)コードをネイティブコードに静的にコンパイルします(おそらくソース-> C->ネイティブなどの中間段階を介して)
  • c)ソースコードを低レベルの中間コードに静的にコンパイルし、実行時に解釈する
  • d)ソースコードを低レベルの中間コードに静的にコンパイルし、初期解釈を使用してから、動的コンパイルと最適化技術を使用してネイティブコードに変換します。コードは、典型的な実行パスとボトルネックが見つかるまで解釈され、その後、典型的な条件下で最速の実行のためにコードがコンパイルされます。実行条件がこれを保証するのに十分なほど変化すると、再コンパイル/再調整されます

あなたの質問:「Javaが(b)C中間コードではなく(d)をJVMで使用する理由は?」

回答:

まず、Scalaはだことを観察くらいCよりも高レベルの言語で、プログラミング能力、プログラミングの容易さ、簡潔さを提供します。ファーストクラス&高階関数、暗黙関数、オブジェクトとしての関数、クロージャーとカリー化、高速スタック保存ループへの末尾再帰のサポート、オブジェクトとしてのすべて、メソッドとしてのすべての演算子により、Javaより約1レベル高いライブラリ、ケースクラス、リダクション(パターンマッチング)、暗黙的な型の派生、拡張された多重継承可能な特性と拡張されたジェネリックによる強力なポリモーフィズム、ペアとタプルとコン(リストとツリー)の組み込み構文で(再)定義できます)&マップ、不変データ構造のサポート、アクター間でメッセージのコピーと受け渡しを行う強力な「リアクティブ」並列および同時コンピューティングのサポート、任意のドメイン固有のDSL、スクリプト可能性、REPLの高度なサポート。Javaは、オブジェクト指向、ポインター管理、ガベージコレクション、文字列サポート、マルチスレッドサポート、同時実行制御、および標準APIライブラリにより、Cより約1レベル高い。

  1. パフォーマンス:高レベル言語の場合、(d)は(a)-(c)よりも高速なパフォーマンスを提供します。
    直接記述され、手作業で最適化されたCコードは高速です。ただし、Cに静的にコンパイルされた高レベル言語は比較的低速です。Javaデザイナーはこれをよく知っていました。現在の「ホットスポット」デザインは、パフォーマンスを最大1桁向上させます。シングルコアでは、Java HotSpotコードは人間が最適化したCの平均「平均50%」です(最良の場合は「120%の高速」、最悪の場合は「30%の高速」)。しかしもちろん、それはリンゴとオレンジを比較しています-低レベルのコードと高レベルのコード。そしてそれは大いになりますホットスポットの最適化が使用されなかった場合はさらに悪化します。確認するには、JVM引数を使用してホットスポットのコンパイルを無効にします!または、ホットスポットが存在しないか未熟であったjava 1&2のパフォーマンスを考慮してください。または、C経由で別の言語-perlccなどをコンパイルしてみてください。したがって、上記は強力で生産的な言語にとって素晴らしい結果です。さらなる開発により、JVMがすぐに平均して手動でコーディングされたCを上回る可能性があります(または可能性が高い)。Scalaは、平均してjavaの70〜80%の速度です。しかし、scalaは複数のコアにまたがって強力にスケーリングします(継続的な改善がさらに進められます)が、javaは部分的に、Cはそうではありません。このような高レベル言語のシングルコアパフォーマンスは次のように評価されます。

    解釈済み<静的にコンパイル<動的にコンパイル

    マルチコアのパフォーマンス/スケーラビリティの評価:

    解釈された動的コード<静的にコンパイルされた命令コード<静的にコンパイルされた機能/宣言コード<動的にコンパイルされた機能/宣言コード

    プロセッサの速度が限界に達し、ムーアの法則によりコアの数が増加しているため、これによりscalaが勝者となりました。Scalaはマルチコアで非常に高速であり、将来的にはCやjavaよりも数倍高速になる可能性があります。Cに静的にコンパイルすることは、明らかに最速のオプションではありません。

  2. 相互運用性:広くサポートされているVM上の言語は、「分離された」言語よりも優れた言語相互運用性を備えています。Scalaは、単にインポートして、あたかもそれらがscalaクラス、特性、およびオブジェクトであるかのように使用することにより、Javaクラス、インターフェース、およびオブジェクトを「自動的に再生」します。Groovy、Clojure、JR​​uby、JPythonなどの他のJVM言語でも同様のことが可能です。相互運用性の容易さは、理解しやすく使いやすいJavaランタイムクラス/インターフェース/オブジェクトにコンパイルするために各言語をどれだけきれいに作成するかに依存します。それは「無料」(「近い」など)のためです。Scalaは、JNIの後継であるJNAを介してCと相互運用します。これには多少の労力が伴いますが、ツールは時間とともに非常に効率化されています。JNAは、任意の言語からコンパイルされたネイティブコードと実際に相互運用できますが、コンパイルされたデータ型と関数の正確な構造を知っている必要があります。そうでない場合、

  3. 移植性:JVMは、数十のオペレーティングシステムプラットフォーム/バージョンで「すぐに」実行できます。 Scalaはこれらに自動的に移植されます。例外はiOS(iPad / iPhone / iPod)です-Appleによって「技術的に」ではなく「商業的に」ブロックされます。これは、JVMの初期設計時に12年前には予想できなかったことです。JVMは、Cをサポートしていないものを含む、他の多数のサーバー、デスクトップ、モバイル、組み込みデバイスで正常に実行されます。確かに、Cコードは多数のプラットフォームで動作するため、Javaの「またはそれ以上」と評価される可能性があります(特に、CはObjective-Cのサブセットです)。しかし、Cは(1)、(2)、および(3)のコストで来ます。 もちろん、iOSのHTML5 / javascript / webkit(またはObjective-C)プレゼンテーションレイヤーは、リモートのscalaアプリと相互運用できます。したがって、開発者はこれを非常によく行う必要があります。もちろん、生産性は低下します。

  4. ツールとライブラリ:明らかに、Scalaを活用/活用できる商用およびオープンソースのJavaライブラリとツールが何千もあります。

  5. セキュリティ: -制御されたアプリサーバーまたはJVM環境で実行すると、セキュリティポリシーと制限に対する強力なサポートが提供されます。これは、企業環境で非常に価値があります。


4

JVM / CLR

JVM(およびCLR)は、最適化とコードの移植性の点で独自の利点を提供します。

私の知る限り、ScalaのJVMバージョンのみが最新に保たれ、.NETバージョンは最新に保たれていません。


3

2つの無関係なものを混ぜているように見えます。

1つ目は、Scalaの作成者がScalaを実装するためにどのプログラミング言語を使用していますか?

その答えは、Scala自体です。そして、それは受け入れられる唯一の答えです。なぜなら、もしあなたがこの新しい言語を発明したのに、それを実装するために自分で使わないなら、それは何の役に立つのでしょうか?

2番目は、Scalaで書かれたプログラムを実行するためのターゲットプラットフォームは何ですか?

ここで選択はより興味深いものになりますが、現時点では、100%動作する唯一のターゲットはJVMです。.NETのサポートは現在進行中です。また、Scalaをjavacsriptにコンパイルするために作業している人もいます。理論的には、C、C ++、LLVM、ネイティブコードなどにコンパイルするための「バックエンド」を追加することを誰かが妨げることはありません。

なぜJVMがプライマリプラットフォームとして選ばれたのですか?私の推測は

  • 誰もがガベージコレクションを望んでいる
  • すぐに使用できる多数の優れたライブラリ
  • 多数のプログラマーがJavaに飽き飽きして、新しいものにジャンプする準備ができているが、JVMの限界にとどまっている(既存のコードを別のプラットフォームに移行したくない)

ガベージコレクターをCまたはC ++で実装できない理由がわかりませんか?私はそれが正当な理由だとは思わない。Pythonがやった。Rubyがやった。ちなみにアーランもそれをやった。ScalaがCまたはC ++で書かれている場合、Scalaがより良いガベージコレクターになることを誰が知っていますか?
ジョシュアパルトギ

1
「本当の」ガベージコレクションを意味しました。このような質問を引き起こすガベージコレクションが十分であるとは思わない。JVMでさえ十分ではありません。そうでなければ、AzulSystemsのような人々は、他の人々がJVMの欠陥を克服するのを助けて生計を立てることができません。
アルテム

また、ライブラリ。ガベージコレクションを使用した言語で明示的なメモリ管理用に記述されたライブラリを使用するのは本当に困難です。1つの兆候は、Javaの人々がすべてを「純粋なJava」で持つという独特の主張です。
アルテム

0

まず、あなたが本当に聞きたかったのは、Scalaが厳密な方法でコンパイルされた言語ではない理由です。わからないよ。ただし、ネイティブコードよりもJVMを優先する理由はないこともお知らせします。

どうして?その理由は簡単です。仮想化テクノロジーはメモリを大量に消費し、不要なオーバーヘッドと間接的な別のレイヤーを生成します。これは実装の問題ではありません。これは、仮想化のコアコンセプトの背後にあるロジックの問題です。あなたが何をしても、常に劣った特性になってしまいます。特にJVMはメモリを大量に消費します。背後で実行される独自のランタイムコンパイラがあるため、もはやそれほど遅くはありませんが、それでも、コンパイラプロセスを実行して、コードの最も混雑した部分を見つけてバイナリコードに変換する必要があります。

そう言った-Scala JVMベースにするために私がそこにいたと思う唯一の理由は、おそらくその言語の人気だった。また、クロスプラットフォームで動作するように組み立てる方法を理解するよりもJVMで言語を実装する方が簡単であり、既存のCバックエンドを使用しても多くの作業が必要であるため、この決定の背後にいくつかの怠inessがあったと思いますJVMほど標準化されていないこと。

それが私が考えることができる理由ですが、それに関連するライセンスの問題や政治のような他の理由があるかもしれないことを覚えておいてください(私はこれまで入りたくない汚いものです)。


-2

より良いチューニングのための能力を持つことが良いトレードオフになるかどうかは明らかではありません。JVMは実行時に最適化を実行できますが、通常、静的コンパイルで通常発生するものより優れていないとしても、少なくともそれで十分です。(明らかに、特定のアプリケーションとワークロードについては、静的最適化でJITを打ち負かすことができるはずですが、実際には、正確なワークロードまたはアプリケーション全体さえもほとんどない場合がほとんどです。)


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