Aleks Bromfieldによるこの主張は次のように述べています。
静的型システムを持つほとんどすべての言語には、動的型システムもあります。C以外に、私は例外を考えることはできません
これは有効な主張ですか?実行時のReflectionクラスまたはLoadingクラスを使用すると、Javaがこのようになりますが、この「漸進型付け」の考え方を多数の言語に拡張できますか?
Aleks Bromfieldによるこの主張は次のように述べています。
静的型システムを持つほとんどすべての言語には、動的型システムもあります。C以外に、私は例外を考えることはできません
これは有効な主張ですか?実行時のReflectionクラスまたはLoadingクラスを使用すると、Javaがこのようになりますが、この「漸進型付け」の考え方を多数の言語に拡張できますか?
回答:
オリジナルのトゥイーターはこちら。:)
まず第一に、私のツイートが真剣に受け止められているのを少し面白がって/ショックを受けました!これが広く普及することになると知っていたら、30秒以上かけてそれを書いていたでしょう!
Thiago Silvaは、型システムではなく、「静的」および「動的」が型チェックをより正確に記述することを指摘するのが正しいです。実際、言語が静的または動的に型付けされていると言っても、実際には正確ではありません。むしろ、言語には型システムがあり、その言語の実装は、静的チェック、動的チェック、またはその両方、またはどちらも使用せずに型システムを強制する場合があります(ただし、非常に魅力的な言語実装ではありません!)。
たまたま、特定のタイプシステム(またはタイプシステムの機能)が静的チェックを受け入れやすくなり、特定のタイプシステム(またはタイプシステムの機能)が動的チェックを受け入れやすくなります。たとえば、特定の値が常に整数の配列でなければならないことをプログラムのテキストで指定できる言語の場合、静的チェッカーを記述してそのプロパティを検証するのは合理的です。逆に、言語にサブタイプがあり、ダウンキャストが許可されている場合、実行時にダウンキャストの有効性をチェックするのはかなり簡単ですが、コンパイル時に行うのは非常に困難です。
ツイートで私が本当に意味したのは、大部分の言語実装が動的な型チェックをある程度実行するということです。または、同様に、大多数の言語には静的にチェックするのが難しい(不可能ではないにしても)いくつかの機能があります。ダウンキャスティングはその一例です。他の例には、算術オーバーフロー、配列境界チェック、およびヌルチェックが含まれます。これらのいくつかは状況によっては静的にチェックできますが、概して、実行時にチェックを行わない言語実装を見つけるのは困難です。
これは悪いことではありません。これは、私たちの言語に適用する多くの興味深いプロパティがあり、静的にチェックする方法が実際にはわからないという観察にすぎません。また、「静的型」と「動的型」のような区別は、一部の人々があなたに信じさせるほど明確ではないことを思い出させてください。:)
最後の注意点:「強い」および「弱い」という用語は、プログラミング言語の研究コミュニティでは実際に使用されておらず、実際には一貫した意味を持ちません。一般に、ある言語には「強いタイピング」があり、他の言語には「弱いタイピング」があると言うとき、彼らは自分の好きな言語(「強いタイピング」を持つ言語)がそれらを妨げると本当に言っていることがわかりました他の言語(「タイピングが弱い」言語)ではできない、または逆に、自分の好きな言語(「タイピングが弱い」言語)が他の言語( 「強いタイピング」のあるもの)はそうではありません。
はい、そうです。静的に型付けされた任意の言語でプロパティバッグを使用できます。構文はひどいものになりますが、同時に動的に型指定されたシステムのすべての不利な点があります。そのため、コンパイラでC#のような優れた構文を使用できる場合を除き、実際には利点はありませんdynamic
。
また、Cでも簡単にできます。
他の答えに対する反応:人々は静的/動的型付けを強い/弱い型付けと間違えていると思います。動的型付けとは、実行時にデータの構造を変更できることと、コードが必要とするものにちょうど適合するデータをコードが使用できることです。これはDuck Typingと呼ばれます。
リフレクションに言及しても、全体を語ることはできません。なぜなら、リフレクションでは既存のデータ構造を変更できないからです。C、C ++、Java、C#のいずれかのクラスまたは構造に新しいフィールドを追加することはできません。動的言語では、既存のクラスに新しいフィールドまたは属性を追加することは可能ですが、実際には非常に一般的です。
例えば、PythonからCへのコンパイラーであるCythonを見てください。静的なCコードを作成しますが、型システムは動的な性質を保持します。Cは静的に型付けされた言語ですが、Pythonからの動的な型付けをサポートできます。
ExpandoObject
、JavaScriptやRubyとは異なり、非常にオプトインプロセスです。それでも、あなたは非常に重要な点を指摘しました。つまり、アヒルのタイピング(開発者の99%が「動的にタイピングされた」と実際に言うもの)とリフレクションはまったく同じものではありません。
True
「このクレイジーなオブジェクトは定義しているクラスのインスタンスです」と言うために戻ることができる魔法のメソッドがあります)。OCamlには、私が理解している限り、この機能がありますが、実際にはわかりません。
動的言語は静的言語です。一般に「動的型付け」と呼ばれるものは、実際には静的型付けの特別な場合です。つまり、1つの型のみに制限している場合です。思考実験として、のみ使用してJavaやC#でプログラムを書いて想像Object
変数/フィールド/パラメータと呼び出す前に、すぐにダウンキャストの任意の方法を。PythonやJavascriptなどの言語を「ユニタイプ」と呼ぶ方が正確です。(この主張は、そのようなJavaまたはC#プログラムが多くのサブタイプを使用することを考えると、多くの人々を混乱させる/仲間にするでしょう。
Cでも「動的な」タイピングを使用できることに注意してください-任意のポインターをvoid
(およびメモリが私に役立つ場合char
)ポインターにキャストし、再び戻すことができます。また、ランタイムチェックは行われないことに注意してください。間違えた場合は、未定義の動作をお楽しみください!
String foo = (String) bar
それを言っているからといって、それがbar
実際にaであることを意味しないString
。それは実行時に確実にしかわからないので、キャストが「静的に」行われる方法はわかりません。
dynamic
これを行うには明示的にオブジェクトを使用する必要があります。プロパティをobject
... に追加しようとすると、できません。
静的および動的型付けの違いはあるとき、コンパイル時間対実行時間を:値の型がチェックされています。値に型が含まれる言語(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 *
。すべてのポインターはに相当します。代わりに、変数と式には型があります。動的な型指定を実現するには、型情報を自分で持ち歩く必要があります(たとえば、構造体のフィールドとして)。
frobnicate
最初にを知らない限り、ここでメソッドを呼び出すことはできませんSpecificType
。
dynamic
キーワードで)。等化静的にコンパイル時および動的なことはするランタイムだけmuddiesにほとんど水を。
[1,2].Add([3,4])
得[1,2,3,4]
、[1,2,[3,4]]
または[4,6]
?
Add
。そのようなメソッドはあいまいになるため、配列を受け入れる配列にはメソッドがないため失敗します。アヒルのタイピングは、わかりやすい型と関数を書くことを許しません。
静的タイピングと動的タイピングは、基本的に、タイプのチェック方法に基づいています。静的型付けとは、さまざまな変数または式の型の検証が実際のコード(通常はコンパイラー)に基づいてチェックされるのに対して、動的型システムではこの検証は実行時環境によって実行時にのみ実行されることを意味します。
テキストが参照していると思うのは、型が実際に静的にチェックされても、実行時にも動的にチェックされるということです。Java Reflectionについて正しく言及しました。リフレクションは実行時にのみ行われ、Javaランタイム環境(JVM)はリフレクションが使用されるときに実際に型チェックを実行します。これは基本的に動的型チェックを意味します。