コンパイルされた言語でインタープリター言語を使用する場合の例は?


11

インタープリター言語とコンパイル言語の違いは理解していますが、誰かがコンパイル言語よりもインタープリター言語を使用する可能性が高い状況や、インタープリター言語よりもコンパイル言語を使用する可能性が高い状況の例を提供できれば、本当に役に立ちます。

回答:


11

(私の知る限り)解釈された「言語」やコンパイルされた「言語」などはありません。

言語はコードのキーワード、フロー構成、その他のさまざまなものの構文と意味を指定しますが、言語仕様でコンパイルまたは解釈する必要があるかどうかを指定する言語はありません。

質問が言語コンパイラと言語インタープリターのどちらを使用するかという場合、実際にはコンパイラーとインタープリターの長所/短所とプロジェクトの目的に帰着します。

たとえば、MRI ruby​​インタープリターの代わりにJRubyコンパイラーを使用して、Javaライブラリーとの統合を容易にすることができます。また、JRubyでMRIルビーインタープリターを使用する理由がある可能性がありますが、私は言語に不慣れであり、これに話すことができません。

通訳の定評のある利点:

  • コンパイルがないため、コードの編集からアプリのテストまでの時間を短縮できます
  • インタープリターがアーキテクチャーの抽象化を管理するため、複数のアーキテクチャーのバイナリーを生成する必要はありません(ただし、バイナリー配布ではなく、スクリプトが整数サイズを正しく処理することを引き続き考慮する必要がある場合あります)

コンパイラーの定評ある利点:

  • コンパイルされたネイティブコードにはインタープリターのオーバーヘッドがないため、通常は時間とスペースがより効率的です。
  • 通常、相互運用性が優れています。スクリプトとのインプロセス相互運用の唯一の方法は、標準のFFIではなくインタープリターを使用することです。
  • インタープリターがコンパイルされていないアーキテクチャーをサポートする機能(組み込みシステムなど)

ただし、90%のケースでは、これはもっと似たようなものになると思います。私は、このソフトウェアをよく知っているので、このソフトウェアをblubで書きたいと思っています。blubインタプリタ(またはコンパイラ)を使用します。これは、blubでソフトウェアを記述するための一般的に受け入れられている標準的な方法であるためです。

したがって、TL; DRは基本的に、特定のユースケースの場合のインタープリターとコンパイラのケースバイケース比較です。

また、FFI:Foreign Function Interface、つまり他の言語と相互運用するためのインターフェイス。ウィキペディアでもっと読む


2
私の知る限り、UNIX用のkshなど、OS用の一部のスクリプト言語はコンパイルできません。
-NoChance

@delnan、私のポイントは、私が知っている商用ソフトウェアまたはフリーソフトウェアを介してコンパイルすることはできません。技術的な理由でコンパイルできないということではありません。
NoChance

3
@EmmadKareem「コンパイルできない」というものはありません。言語Liでプログラムを読み取り、言語Laで同等のプログラムを出力するプログラムを作成します。これはコンパイラーであり、コンパイラーです。チューリング完全性の議論は、実際には赤いニシンであるため、ためらうことはありませんが、各プログラムは最終的にはマシンコード命令のシーケンスに変わります。他のすべてが失敗した場合、インタープリターループを展開します(そして、結果のコードを単純化して、不要な部分を削除します)。インタープリターがインタープリターのない言語で書かれている場合、コンパイラーで何かを見つけるまで繰り返します。

1
(私はコメントを編集して表現を改善しましたが、明らかに遅すぎたようです。)@EmmadKareemはい、明らかにいくつかの言語はコンパイラを介して実装されませんでした。しかし、私はこれがどのように関連するのか見当たりません。そうすることは常に可能であり実現可能であり、いつでも努力を払って行うことができます。これは主な点の結果です。つまり、言語は本質的にコンパイルも解釈もされず、両方の方法で実装できます。ちなみに、他の無数の方法(まあ、間違いなくマイナーなバリアントとリミックス)です。

2
@EmmadKareem必要に応じて、ksh言語仕様を取得し、それを読み取ってネイティブバイナリを生成するコンパイラを作成できます。ここでの私のポイントは、コンパイルまたは解釈される言語が言語の定義にないことです。
ジミー・ホッファ

8

ここで重要な点は、多くの言語実装が実際に両方のハイブリッドを何らかの形で行うことです。現在一般的に使用されている多くの言語は、プログラムをバイトコードなどの中間形式にコンパイルし、それをインタープリターで実行することで機能します。これが、Java、C#、Python、Ruby、およびLuaの一般的な実装方法です。実際、これはほぼ間違いなく、現在使用されているほとんどの言語が実装されている方法です。そのため、今日の言語はコードを解釈およびコンパイルします。これらの言語の一部には、実行のためにバイトコードをネイティブコードに変換する追加のJITコンパイラがあります。

私の意見では、今日の言語実装の複雑さを区別するための有用なカテゴリではなくなったため、インタープリター言語とコンパイル言語について話すのをやめるべきです。

インタープリター言語とコンパイル言語のメリットについて尋ねると、おそらく何か別の意味があります。静的/動的型付けのメリット、ネイティブ実行可能ファイルの配布のメリット、JITおよびAOTコンパイルの相対的な利点について質問しているかもしれません。これらはすべて、解釈/コンパイルと混同される問題ですが、異なる問題です。


2

まず第一に、プログラミング言語は解釈もコンパイルもできます。解釈とコンパイルは、ソースコードから実行可能コードを生成する単なる方法です。インタープリターを使用すると、ソースコードはインタープリターによって読み取られて解釈され、インタープリターはコードを解釈しながら実行します。一方、コンパイラはソースコードを読み取り、ソースコードから実行可能なバイナリファイルを生成します。これにより、プログラムを独立したプロセスとして独立して実行できます。

誰もが疑問に思う前に...はい、C / C ++ / C#/ Javaを解釈できます。そして、はい、JavaScriptとBashスクリプトをコンパイルできます。ただし、これらの言語用に動作するインタープリターまたはコンパイラーがあるかどうかは別の質問です。

「コンパイルされた言語」ではなく「解釈された言語」を使用する場合、実際に質問に答えます。質問自体はやや混乱しますが、コンパイルよりも解釈を優先するタイミングを意味していると思います。コンパイルの欠点の1つは、コンパイルプロセスのためにオーバーヘッドが発生することです。ソースコードを実行可能なマシンコードにコンパイルする必要があるため、ソースコードを呼び出してプログラムを実行するときに最小限の遅延が必要なタスクには適していません。一方、コンパイルされたソースコードは、コードの解釈に起因するオーバーヘッドのため、ほとんどの場合、同等の解釈されたソースコードよりも高速です。一方、通訳者はソースコードを呼び出して実行できます 呼び出しオーバーヘッドはほとんどありませんが、実行時のパフォーマンスが犠牲になります。

最終的に、次々に好む場合に明確なユースケースを述べることはほぼ不可能ですが、たとえば、(私のアンダーサンディングは非常に非現実的です)プログラムの呼び出しの間でプログラムのソースコードが動的に変化し、コンパイルのオーバーヘッドがあまりにも大きい場合です実行可能な選択であるために高い。その場合、コンパイルする代わりにソースコードを解釈することがおそらく望ましいでしょう。

ただし、実世界の例と見なすことができるものがあります。展開時のソースコードの隠蔽です。ネイティブ開発者がプロ​​グラムとデータの実行可能なmacineコードをデプロイするコンパイル済みコード。インタープリターコードでは、ソースコード自体を展開する必要があります。ソースコードは、ネイティブマシンコードをリバースエンジニアリングするよりもはるかに少ない労力で検査およびリバースエンジニアリングできます。これの1つの例外は、C#やJavaのような言語で、即時言語/バイトコード(C#のMSILおよびJavaのJavaバイトコード)にコンパイルされ、実行時に「ジャストインタイム」で展開およびコンパイルされます。ただし、元のソースコードを比較的正確に再構築できるMSILおよびJavaバイトコード用のいわゆる逆コンパイラーが存在します。そのような製品のリバースエンジニアリングは、ネイティブマシンコードで展開されるリバースエンジニアリング製品よりもはるかに簡単です。


1
あなたは良い点を述べていますが、私は教訓的であるため、いくつかの言い回しに問題があります(両方とも3番目の段落を参照)。1.インタープリターがコンパイルされません。2.最適化されていない悪いコンパイラが高度に最適化された(特にバイトコードベースの)インタプリタによって破られるのは(これらの条件はまれですが)分かりやすいです。JITコンパイラーをインタープリターの下に数える場合、これは二重になります(私はそれを好まないが、それをする人もいます)。

@delnanおそらく言葉が間違っているかもしれませんが、私は英語を母国語としていません。しかし、私が知る限り、3番目の段落はインタープリターがコンパイルされることを意味しません。2番目の点については、コンパイルされ解釈されたコードの類似性を強調することと同等の言葉に重点を置いて、貧弱なコンパイラー対高性能インタープリターのケースを除外しましたが、おそらく明確ではなかったかもしれませんが、私はそれを見ません極端な場合の説明に焦点を当てるのは合理的で、ソースコードをコンパイルまたは反復することでソースコードを実行することの違いに何の貢献もないため、
zxcdw

申し訳ありませんが、最初の点は決して気にしないでください。カルパ。2番目の点については、解釈またはコンパイルされるコードを「同等」に参照しました(コンパイラーとインタープリターを比較することは、根本的に異なることを行うため、あまり意味がありません)。私の例のような風変わりなケースの詳細を説明するのに時間を浪費すべきではないと思いますが、そもそもなぜそれ速くなるのを説明するフレーズを支持して、「常に」を捨てる方がいいと思います。定義された私見]、および実行前に最適化を実行する機会。

1

インタプリタ言語を使用する場合、次のシナリオを考えることができます。

  • Linux / Unix シェルスクリプトなどのコンパイラが存在しない場合。
  • 小さな問題を解決する迅速で汚いスクリプト
  • 動的なHTMLページを簡単に記述できる言語で、一般的にJSP(Tomcatはそれをサーブレットにコンパイルして実行します)、PHP、ASPなどのように解釈されます。

コードコンパイルしたいときは、次のシナリオを考えることができます

  • アプリはクローズドソースであり、ソースコードを公開したくないため、バイナリ配布する必要があります。
  • 組み込みシステムなどの速度。
  • 厳密に型指定された言語を使用するコンパイラのみが提供できるレベルのコード型安全性が必要です。コンパイラは、ソースコードの隅々にタイプミスを公開しますが、解釈されたプログラムでは、タイプミスがプロダクションコードに発見されることはありません。
  • 大規模で複雑なシステム:コンパイルされたバイナリ以外のOSやオフィススーツを想像することはできません。
  • 少しのオーバーヘッドをすべて取り除き、アセンブラスニペット(あらゆる種類のランタイム、特にインタープリタとのハード)との良好なコミュニケーションが必要です(この点は@delnamコメントによってもたらされます)

3
言語インタープリターは、言語をそれほど強く型付けしません。Haskellは非常に強く型付けされており、GHCIを使用して効果的に解釈できます。強い/弱いタイピングは言語の側面であり、コンパイラまたはインタープリターの側面ではありません。
ジミー・ホッファ

1
-1コンパイルの長所:(1)コードのコンパイルはリバースエンジニアリングから保護せず、わずかに難しくします。(2)コンパイル(インタープリターのオーバーヘッドの除去、アプリケーションコードの自動最適化)は、パフォーマンスの1つのソースに過ぎず、人間の専門家による手作業による大規模な最適化によって凌isされます。(3)型チェックは、通常はコンパイルと組み合わされていますが、独立しています。型チェッカーは静的分析パスです。コードを出力せずにコードを解釈する前に発生する可能性があります。(4)かなり誤っているようです。あなたはそれを「想像できません」?どうして?どのように必要ですか?

1
他のプログラムにインタープリターが存在する場合は常に、他のインタープリター言語が存在します。インタープリターパターンを使用している場合は常に、ある程度複雑なインタープリター言語があります。

3
「スクリプト」は必ずしも解釈されません。多くの「スクリプト」言語は、実行される仮想マシンのバイトコードにコンパイルされます(lua、perl、python、rubyを参照)。コンパイルが行われるとき以外は、これとjavaの間に実際の違いはありません。

3
+1、私はそれがOPが本当に求めていた種類の答えだと思います、そして指摘されたようにポイントは100%真実ではないかもしれませんが、実用的な考慮事項には少なくとも95%真実があります。
ドックブラウン

1

結局、大きなトレードオフは、生産性(コードの行数を記述する必要があります)とパフォーマンス(プログラムの実行速度)の間です。

ためインタプリタ言語 CPU情報に変換多くの情報を持っている、彼らが頼ることができる反射および動的型付け大幅に生産性を向上させます。インタープリター言語のもう1つの利点は、プラットフォーム用のインタープリターが存在する限り、プラットフォームに依存しないことです。

解釈された場合のように、CPUがマシンコードの言語コードを変換し、同時にコードを実行してはならないため、コンパイルされた言語はより高速なプログラムを生成します。また、コンパイルされた言語で構築されたシステムは、コンパイル時に問題を検出できるためより安全です。これは、実際にプログラムを実行するときにのみ表示されるのではなく、入力時にエラーが表示されることを意味します(もちろん) 、これは論理エラーを修正しません)。

これを知って、インタプリタ言語は以下に適しています:

  1. 生産的な開発:高速Web開発(PHP、Javascript)またはプロトタイピング用。
  2. クロスプラットフォーム; たとえば、JavaScriptはすべてのブラウザー(モバイルブラウザーを含む)でサポートされています。

コンパイルされた言語は次の場合に適しています。

  1. パフォーマンスが重要(オペレーティングシステム)またはリソースが少ない(マイクロコントローラー)。
  2. 構築するシステムは複雑です。大規模システム(エンタープライズシステム)を構築する場合、コンパイルされた言語は、インタープリタ言語に現れる可能性のある多くのバグを処理するために不可欠です。また、複雑なプログラムには多くのリソースが必要であり、バランスも言語をコンパイルする傾向があります。

-1すべての解釈言語は動的に型付けされ、すべてのコンパイルされた言語は静的に型付けされることを意味するため、これは完全に誤りです。
ダニエル・プライデン

@DanielPrydenそれは純粋な偶然でなければなりません、ほとんどすべての解釈された言語が動的に型付けされ、コンパイルされた言語が静的に型付けされるという事実?動的型モデルがインタープリター言語に適しているのは偶然ですか?
m3th0dman

さまざまな理由により、相関関係がありますが、それは要件ではありません。これは実際にStackOverflowで尋ねられました:なぜ解釈されたlangsはほとんどがコンパイルされている間にducktypedされているのですか?
ダニエル・プライデン

1
Erlangはコンパイルされ、動的に型付けされます。Haskellは静的に型付けされ、コンパイルまたは解釈することができる
ザカリーKを

1
@ZacharyK Erlangにはランタイムシステムがあります。Haskellは、ほとんどの場合(書かれたプログラム)にコンパイルされます。
m3th0dman

1

他の人が述べた理由に加えて、コンパイルまたはハイブリッドアプローチの形式よりもアドホックな解釈を選択するための1つの特に重要なユースケースがあります。

プログラミング言語が通信プロトコルとして使用されている場合、および応答の待ち時間が重要な場合、コンパイルおよび可能な前処理に時間を浪費しないようにする方が理にかなっています。

これは、たとえばエージェント言語、またはTcl / Tkの通常の使用方法などに適用されます。

解釈に固執するもう1つの考えられる理由は、言語インタープリターがそれ自体またはより複雑で高レベルの言語のブートストラップに使用され、その単純さがブートストラッププロセスのパフォーマンスよりも重要な場合です。

他のほぼすべての可能なユースケースでは、コンパイル(またはハイブリッドアプローチ)が適しています。

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