静的に型付けされた言語と動的に型付けされた言語は、原理的には反対の概念のように見えます。しかし、たとえば Objective-C のような言語が、これらの両方を一度に実現するにはどうすればよいでしょうか? 私には、Objective-C は動的というよりも静的なように思えます。誰かがこれがどのように可能かを説明できますか?
6 に答える
静的型付けと動的メソッド解決を混同していると思います。Objective-C は間違いなく強力に静的に型付けされています。C と同様に、すべての変数を宣言して型指定する必要があります (他の最新の静的に型付けされた言語のような型推論さえありません)。コンパイラは変数の型に基づいてコードを生成しますが、この型は実行時に変更できません。
ただし、Objective-C のメソッド呼び出しではメッセージ パッシング パラダイムが使用されます。この場合、メッセージ名とターゲットはコンパイル時にエンコードされますが、実行するコードのアドレスは Objective-C ランタイム ライブラリによって実行時に検索されます。
Objective-C は、実際には (概念的には) C 言語自体のレイヤーにすぎないため、静的型と動的型の両方を持つことができます。Base-C のものを使用している場合は静的、Objective-C 拡張機能を使用している場合は動的です。
しかし、C もこの機能を提供しています。C の void * 型について考えてみると、任意の型を指すことができるため、(非常に大雑把な) 動的に型付けされた言語が得られることがわかります。
例えば:
int i;
float f;
double d;
void *p = &i;
p = &f;
p = &d;
上記のすべての割り当てでp
、別の型を指すように作られています。コードを十分に巧みに作成すれば、RTTI とポリモーフィズムを C でエミュレートすることさえできます。
私は、主に静的または動的に型付けされた言語を、その言語が最も使用された目的に基づいて検討します。
C は静的に型付けされた言語ですが、型を他の型に再キャストしたり、ジェネリック ポインター (void* 型) を使用したりできる柔軟性があります。void* 型は、「不特定の型のデータへのポインタ」を意味します。Objective-C は、これらの void* 型を使用して動的型を実装しますが、通常、これは複数レベルの定義、typedef などによって抽象化されています。
両方のイディオムをサポートする技術的能力について質問している場合、それは特に興味深い質問ではありません。現代のほとんどの言語を見て、どのようにそれを行っているかを見てください。通常、これはある種の包括的な動的型 ( Object
VB、dynamic
C#、void*
C など) を介して行われます。
形而上学的/存在論的レベルでは、この質問ははるかに興味深いものです...
物理学の理論は、直感に反する行動を示唆し、「どうしてそんなことができるの?」と疑問を抱かせるかもしれません。たとえば、波動と粒子の二重性は、現実がどうあるべきか、どうあるべきかについての常識的な概念を超えているため、私たちは計り知れないことを考えさせられます。
ただし、プログラミング言語は現実のモデルではありません。それらは、私たちの目的に役立つように設計された心の発明です。したがって、プログラミング言語がどのようにあり得るかを考えても意味がありません。そのようにしたかったので、そのようになりました。私たちの目的に合っているからです。他の理由は必要または保証されません。
ですから、言語が動的にも静的にもなり得るという理由だけでそれが可能であり、これが有用であるという理由だけで、言語が動的にも静的にもなり得ると答えるとき、私は軽薄または否定的ではないことを理解してください. これ以上の調査を試みることは絶望的です。
Objective-C には、静的型付けと動的型付けが混在しています。普通の C オブジェクトは静的に型付けされますが、Objective-C オブジェクトは動的に型付けされます。オブジェクトに送信したメッセージがオブジェクトによって認識される限り、Objective-C ランタイムはオブジェクトの型を気にしません。