型システムは、正確性のいくつかの側面を自動的に検証できる証拠です。たとえば、Rustの型システムは、参照が参照オブジェクトよりも長く存続しないこと、または参照オブジェクトが別のスレッドによって変更されていないことを証明できます。
しかし、型システムはかなり制限されています:
彼らはすぐに決定可能性の問題に遭遇します。特に、型システム自体は決定可能である必要がありますが、実際の型システムの多くは誤ってTuring Completeです(テンプレートによるC ++と特性によるRustを含む)。また、彼らが検証しているプログラムの特定のプロパティは、一般的なケースでは決定できない可能性があります。最も有名なのは、一部のプログラムが停止(または発散)するかどうかです。
さらに、型システムは、理想的には線形時間ですばやく実行する必要があります。可能なすべての証明が型システムで取り上げられるべきではありません。たとえば、プログラム全体の分析は通常避けられ、証明は単一のモジュールまたは関数に限定されます。
これらの制限があるため、型システムは、たとえば関数が正しい型の値で呼び出されているなど、証明しやすいかなり弱いプロパティのみを検証する傾向があります。それでも表現力が大幅に制限されるため、回避策(interface{}
Go、dynamic
C#、Object
Java、void*
Cなど)を使用することや、静的型付けを完全に回避する言語を使用することも一般的です。
検証するプロパティが強いほど、その言語で得られる表現は少なくなります。Rustを作成した場合、正しいことが証明できなかったために、コンパイラが一見正しいコードを拒否する「コンパイラとの戦い」の瞬間を知っています。場合によっては、Rustで特定のプログラムを正確に証明できると信じていても、そのプログラムを表現できないことがあります。unsafe
RustまたはC#のメカニズムを使用すると、型システムの制限を回避できます。場合によっては、チェックを実行時に延期することも別のオプションになりますが、これは、一部の無効なプログラムを拒否できないことを意味します。これは定義の問題です。パニックに陥るRustプログラムは、型システムに関する限り安全ですが、必ずしもプログラマーやユーザーの観点からはそうではありません。
言語は型システムと一緒に設計されています。新しい型システムが既存の言語に課されることはまれです(ただし、MyPy、Flow、TypeScriptなどを参照してください)。言語は、たとえば型注釈を提供することによって、または簡単に証明できる制御フロー構造を導入することによって、型システムに準拠するコードを簡単に記述できるようにします。言語が異なれば、解決策も異なる場合があります。たとえば、Javaには、final
Rustの非mut
変数と同様に、1回だけ割り当てられる変数の概念があります。
final int x;
if (...) { ... }
else { ... }
doSomethingWith(x);
Javaには、すべてのパスが変数を割り当てるか、変数にアクセスする前に関数を終了するかを決定する型システムルールがあります。対照的に、Rustは宣言されているが設計されていない変数を持たないことでこの証明を簡略化しますが、制御フローステートメントから値を返すことができます。
let x = if ... { ... } else { ... };
do_something_with(x)
これは、割り当てを理解する上で非常にマイナーなポイントのように見えますが、明確なスコープは、生涯に関連する証明にとって非常に重要です。
Rustスタイルの型システムをJavaに適用する場合、それよりもはるかに大きな問題が発生します。Javaオブジェクトにはライフタイムの注釈が付けられないため、&'static SomeClass
またはとして扱う必要がありArc<dyn SomeClass>
ます。それは結果として生じる証明を弱めるでしょう。また、Javaには不変性の型レベルの概念がないため、&
と&mut
型を区別できません。オブジェクトはCellまたはMutexとして扱う必要がありますが、これはJavaが実際に提供するよりも強力な保証であると想定される場合があります(Javaフィールドの変更は、同期および揮発性でない限りスレッドセーフではありません)。最後に、RustにはJavaスタイルの実装継承の概念がありません。
TL; DR:型システムは定理を証明します。ただし、決定可能性の問題とパフォーマンスの問題によって制限されます。ターゲットの言語構文が必要な情報を提供しない場合や、セマンティクスに互換性がない場合があるため、1つの型システムを別の言語に適用することはできません。