私はそれを知りません、それには技術的な理由がありますか?型付けが弱い言語のコンパイラを実装するのは難しいですか? それは何ですか?
9 に答える
質問の背後にある前提は少し危険です。インタプリタ言語がほとんどダックタイプであるというのは真実ではありません。コンパイルされた言語が主に強い型付けを持っているというのは真実ではありません。型システムは言語のプロパティです。 コンパイルされたものと解釈されたものは、実装のプロパティです。
例:
プログラミング言語Schemeは動的に型付けされ(別名duck-typed)、数十の解釈された実装がありますが、Larceny、Gambit、PLT Scheme(インタプリタとJITコンパイラの両方を含む)を含むいくつかの優れたネイティブコードコンパイラもあります。シームレスな移行)。
プログラミング言語Haskellは静的に型付けされています。最も有名な2つの実装は、インタープリターHUGSとコンパイラーGHCです。ネイティブコードへのコンパイル(yhc)と解釈(Helium)の間でほぼ均等に分割された他のいくつかの立派な実装があります。
プログラミング言語のStandardMLは静的に型付けされており、多くのネイティブコードコンパイラがあります。そのうちの1つはMLtonですが、最も有用な実装の1つはインタプリタMoscowMLです。
プログラミング言語ObjectiveCamlは静的に型付けされています。(フランスのINRIAからの)実装は1つだけですが、この実装にはインタープリターとネイティブコードコンパイラの両方が含まれています。
プログラミング言語Pascalは静的に型付けされていますが、Pコードインタープリターに基づいたUCSDで構築された優れた実装により、1970年代に普及しました。後年、370シリーズのコンピューター用のIBM Pascal / VSコンパイラーなど、優れたネイティブコードコンパイラーが利用可能になりました。
プログラミング言語Cは静的に型付けされており、今日ではほとんどすべての実装がコンパイルされていますが、1980年代には、SabreCを使用できる幸運な人たちはインタープリターを使用していました。
それにもかかわらず、あなたの質問の背後にはいくつかの真実があるので、あなたはもっと思慮深い答えに値します。真実は、動的に型付けされた言語は、解釈された実装と相関しているように見えるということです。なぜそうなのか?
多くの新しい言語は、実装によって定義されます。コンパイラを構築するよりもインタプリタを構築する方が簡単です。静的にチェックするよりも動的にタイプをチェックする方が簡単です。また、インタープリターを作成している場合、静的型チェックによるパフォーマンス上の利点はほとんどありません。
非常に柔軟なポリモーフィック型システムを作成または適応させない限り、静的型システムはプログラマーの邪魔になる可能性があります。しかし、インタプリタを作成している場合、1つの理由は、プログラマーの邪魔にならないように、小さくて軽量な実装を作成することかもしれません。
一部のインタプリタ言語では、多くの基本的な操作が非常に高価であるため、実行時に型をチェックする追加のオーバーヘッドは問題になりません。 良い例はPostScriptです。帽子をかぶっただけでベジェ曲線を実行してラスタライズする場合は、あちこちでタイプタグをチェックすることを躊躇することはありません。
ちなみに、「強い」と「弱い」という用語は、普遍的に合意された技術的な意味を持っていないため、注意してください。対照的に、静的型付けとは、プログラムが実行される前にチェックされ、プログラムが開始される前に拒否される可能性があることを意味します。 動的型付けとは、実行中に値の型がチェックされることを意味します。型指定が不十分な操作により、プログラムが停止したり、実行時にエラーが通知されたりする可能性があります。。静的型付けの主な理由は、このような「動的型エラー」が発生する可能性のあるプログラムを除外することです。(これは、インタープリターを作成する人々が静的型付けにあまり関心がないもう1つの理由です。実行は型チェックの直後に行われるため、保証の違いと性質はそれほど明白ではありません。)
強い型付けは一般に型システムに抜け穴がないことを意味しますが、弱い型付けは型システムを破壊できることを意味します(保証を無効にします)。これらの用語は、静的型付けと動的型付けを意味するために誤って使用されることがよくあります。違いを確認するために、Cについて考えてみてください。言語はコンパイル時に型チェックされます(静的型付け)が、抜け穴がたくさんあります。ほぼすべての型の値を同じサイズの別の型にキャストできます---特に、ポインタ型を自由にキャストできます。Pascalは強く型付けされることを目的とした言語でしたが、有名なことに予期しない抜け穴がありました。タグのないバリアントレコードです。
強く型付けされた言語の実装は、通常、ランタイムシステムの一部を高級言語で実装できるように、時間の経過とともに抜け穴を獲得することがよくあります。たとえば、Objective Camlには、Obj.magic
引数を返すだけの実行時効果を持つという関数がありますが、コンパイル時に、任意のタイプの値を他のタイプの1つに変換します。私のお気に入りの例はModula-3で、その設計者は型キャスト構造と呼んでいLOOPHOLE
ます。
要約すれば:
静的vs動的は言語です。
コンパイルされたものと解釈されたものが実装です。
原則として、2つの選択は直交することができ、直交して行われますが、技術的な理由から、動的型付けは解釈と相関することがよくあります。
動的 (ダック) 型付けを使用する言語は、怠惰なプログラマーが好む遅延評価を採用しており、怠惰なプログラマーはコンパイラーを書くのが好きではないと推測しています;-)
一部の言語は、例外的でない状況で完璧に動作するように意図されており、例外的な状況で発生する恐ろしいパフォーマンスのために犠牲になっているため、非常に強力な型付けになります。他のものは、追加の処理とのバランスをとるだけのものでした.
時には、単にタイピングするだけではありません。たとえば、ActionScript を取り上げます。3.0 ではより強力な型付けが導入されましたが、ECMAScript では実行時に適切と思われるクラスを変更でき、ActionScript では動的クラスがサポートされています。非常にきちんとしていますが、動的クラスを「標準」ビルドで使用すべきではないと述べているという事実は、安全にプレイする必要がある場合には、それはノーノーであることを意味します.