この主張Aleks Bromfield による:
静的型システムを持つほとんどすべての言語には、動的型システムもあります。 Cを除いて、私は例外を考えることができません
これは有効な主張ですか?実行時にリフレクションクラスまたはロードクラスを使用すると、Javaはこのようになりますが、この「段階的な型付け」のアイデアを多数の言語に拡張できますか?
オリジナルのツイーターはこちら。 :)
まず第一に、私は私のツイートがとても真剣に受け取られていることに多少面白がって/ショックを受けています!これが広く普及することを知っていたとしたら、30秒以上も書いていたことでしょう。
Thiago Silvaは、「静的」および「動的」がタイプsystemsではなくタイプcheckingをより正確に説明していることを指摘するのは正しいです。実際、言語が静的または動的に型付けされていると言っても、それほど正確ではありません。むしろ、言語には型システムがあり、その言語の実装は、静的チェックまたは動的チェック、あるいはその両方を使用して型システムを強制するか、またはその両方を実行します(ただし、それほど魅力的な言語実装ではありません!)。
偶然にも、静的チェックの影響を受けやすい特定の型システム(または型システムの機能)と、動的チェックの影響を受けやすい特定の型システム(または型システムの機能)があります。たとえば、特定の値が常に整数の配列でなければならないことをプログラムのテキストで指定することが言語で許可されている場合、そのプロパティを検証する静的チェッカーを書くのはかなり簡単です。逆に、言語にサブタイプがあり、ダウンキャストが許可されている場合は、実行時にダウンキャストの有効性をチェックするのはかなり簡単ですが、コンパイル時にチェックするのは非常に困難です。
私のツイートで私が本当に意味しているのは、言語実装の大部分がsome量の動的型チェックを実行するということです。あるいは、同等に、大多数の言語には静的にチェックすることが(不可能ではないにしても)難しいsome機能があります。ダウンキャストはその一例です。その他の例には、算術オーバーフロー、配列境界チェック、およびnullチェックが含まれます。これらの一部は状況によって静的にチェックできますが、概して、実行時にチェックを行わない言語実装を見つけるのは困難です。
これは悪いことではありません。私たちの言語に強制したい多くの興味深いプロパティがあり、静的にチェックする方法が本当にわからないというのは単なる観察です。また、「静的型」と「動的型」のような違いは、一部の人が信じているほど明確ではないことを思い出させてくれます。 :)
最後に、「強い」と「弱い」という用語は、プログラミング言語の研究コミュニティでは実際に使用されておらず、一貫した意味を持っているわけではありません。一般的に、ある言語に「強い入力」があり、他の言語に「弱い入力」があると誰かが言ったとき、彼らは自分の好きな言語(「強い入力」のある言語)が他の言語(「弱いタイピング」のある言語)はそうではない、または逆に、お気に入りの言語(「弱いタイピング」のある言語)が他の言語( 「強い型付け」のあるものはそうではありません。
はい、そうです。静的に型付けされた言語でプロパティバッグを持つことができます。構文はひどいものですが、同時に動的に型付けされたシステムのすべての欠点を得るでしょう。そのため、コンパイラがdynamic
を指定したC#のように、より良い構文を使用できるようにしない限り、実際には何の利点もありません。
また、Cでもかなり簡単に実行できます。
他の答えに対する反応:私は人々が静的/動的型付けを強い/弱い型付けと間違えていると思います。動的型付けとは、実行時にデータの構造を変更できること、およびコードがコードに必要なものにぴったり合うデータを使用できるようにすることです。これは Duck Typing と呼ばれます。
リフレクションではデータの既存の構造を変更できないため、リフレクションについて言及しても全体像はわかりません。 C、C++、JavaまたはC#のいずれかでクラスまたは構造に新しいフィールドを追加することはできません。動的言語では、既存のクラスに新しいフィールドまたは属性を追加することは可能であるだけでなく、実際には非常に一般的です。
たとえば、Python-to-Cコンパイラである Cython を見てください。静的Cコードを作成しますが、型システムは動的な性質を保持しています。 Cは静的に型付けされた言語ですが、Pythonからの動的な型付けをサポートできます。
動的言語は静的言語です 。一般に「動的型付け」と呼ばれるものは、実際には静的型付けの特別なケースです。つまり、型を1つだけに制限した場合です。思考実験として、JavaまたはC#でObject
変数/フィールド/パラメーターのみを使用し、呼び出しの直前にダウンキャストするanyメソッドです。PythonまたはJavascript "unityped"のような言語を呼び出す方がより正確です。(この主張は、多くの人々を混乱/混乱させる可能性があります。このようなJavaまたはC#プログラムでは多くのサブタイプが使用されますが、これは平均的なOOP言語がタイプとクラスを統合するためです。詳細)
Cでさえ「動的」な型付けがあることに注意してください。void
(およびメモリが私に役立つ場合はchar
)ポインターにポインターをキャストして、再び戻すことができます。また、実行時チェックは行われないことにも注意してください。間違えた場合は、未定義の動作を楽しんでください!
静的型付けと動的型付けの違いはwhen値の型がチェックされる:コンパイル時と実行時。 valuesで型を運ぶ言語(例Javaオブジェクト))では、言語が実際に静的型付けを好む場合でも、常に動的型付けに頼ることができます。動的に型付けされたメソッドを使用したJavaの例:
void horribleJava(List untypedList) {
for (Object o : untypedList)
((SpecificType) o).frobnicate();
}
実行時に各アイテムのタイプがどのようにチェックされるかに注意してください。同等の静的型付けメソッドは次のとおりです。
void goodJava(List<SpecificType> typedList) {
for (SpecificType o : typedList) {
o.forbnicate();
}
}
Cでは、値(特にポインター)は実行時に型を保持しません。すべてのポインターはvoid *
と同等です。代わりに、variablesおよび式にはタイプがあります。動的型付けを実現するには、型情報を自分で(たとえば、構造体のフィールドとして)持ち運ぶ必要があります。
静的型と動的型では、基本的に型のチェック方法を参照します。静的型付けとは、さまざまな変数または式の型の検証が実際のコードに基づいて(通常はコンパイラーによって)チェックされることを意味しますが、動的型システムでは、この検証はランタイム時にのみランタイム環境によって実行されます。
テキストが参照していると私が信じているのは、型が実際に静的にチェックされている場合でも、実行時に、つまり動的にチェックされることです。 Javaリフレクション;リフレクションは実行時にのみ発生し、Javaランタイム環境(JVM)は、リフレクションが使用されるときに実際に型チェックを実行します。型チェック。