型システム


Type_system

は、コンピュータプログラミングの観点からの型システムについてです。理論的な再定式化については、型理論を参照してください
プログラミング言語、型システムは、ある論理システムと呼ばれるプロパティ割り当てルールのセットを含むタイプの種々の構築物へのコンピュータプログラムのような、変数、式、関数又はモジュールは。これらの型は、プログラマーが代数的データ型、データ構造、またはその他のコンポーネント( “string”、 “array of float”、 “function return boolean”など)に使用する暗黙のカテゴリーを形式化して適用します。型システムの主な目的は、バグの可能性を減らすことですコンピュータプログラムでは、コンピュータプログラムのさまざまな部分の間のインターフェイスを定義し、それらの部分が一貫した方法で接続されていることを確認します。このチェックは、静的(コンパイル時)、動的(実行時)、または両方の組み合わせとして実行できます。型システムには、ビジネスルールの表現、特定のコンパイラの最適化の有効化、複数のディスパッチの許可、ドキュメントの形式の提供など、他の目的も
型システムは、型を各計算値に関連付け、これらの値のフローを調べることにより、型エラーが発生しないことを確認または証明しようとします。問題の特定の型システムは、何が型エラーを構成するかを決定しますが、一般に、目的は、特定の種類の値を期待する操作が、その操作が意味をなさない値(有効性エラー)で使用されないようにすることです。型システムは、プログラミング言語の一部として指定され、インタープリターとコンパイラーに組み込まれることがよくありますが、言語の型システムは、言語の元の型構文と文法を使用して追加のチェックを実行するオプションのツールによって拡張できます。

コンテンツ
1 使用方法の概要
2 基礎
2.1 タイプエラー
3 タイプチェック
3.1 静的型チェック 3.2 動的型チェックと実行時型情報 3.3 静的型チェックと動的型チェックの組み合わせ 3.43.4 実際の静的および動的型チェック 3.5 強い型と弱い型システム 3.6 タイプの安全性とメモリの安全性 3.7 可変レベルの型チェック 3.8 オプション型システム
4 ポリモーフィズムとタイプ
5 特殊型システム
5.1 依存型 5.2 線形型 5.3 交差型 5.4 共用体タイプ 5.5 存在型 5.6 漸進的型付け
6 明示的または暗黙的な宣言と推論
7 決定問題
8 統一型システム
9 互換性:同等性とサブタイピング
10 も参照してください
11 ノート
12 参考文献
13 参考文献
14 外部リンク

使用方法の概要
単純型システムの例は、C言語のシステムです。Cプログラムの部分は関数定義です。ある関数が別の関数によって呼び出されます。関数のインターフェースは、関数の名前と関数のコードに渡されるパラメーターのリストを示します。呼び出し元の関数のコードは、呼び出された関数の名前と、それに渡される値を保持する変数の名前を示します。実行中、値は一時ストレージに配置され、実行は呼び出された関数のコードにジャンプします。呼び出された関数のコードは値にアクセスし、それらを利用します。関数内の命令が整数値を受け取ることを前提として記述されているが、呼び出し元のコードが浮動小数点値を渡した場合、呼び出された関数によって誤った結果が計算されます。Cコンパイラーは、関数が呼び出されたときに関数に渡された引数のタイプを、関数の定義で宣言されたパラメーターのタイプと照合します。タイプが一致しない場合、コンパイラはコンパイル時エラーをスローします。
コンパイラはまた、それが必要とストレージと値の操作のためのアルゴリズムの選択を最適化するために、値の静的な型を使用することができます。多くのCコンパイラでは、たとえば、float データ型は32ビットで表され、単精度浮動小数点数のIEEE仕様に準拠しています。したがって、これらの値に対して浮動小数点固有のマイクロプロセッサ操作(浮動小数点の加算、乗算など)を使用します。
タイプ制約の深さとその評価方法は、言語のタイピングに影響を与えます。プログラミング言語は、さらに、の場合に、各タイプのための様々な解像度での動作を関連付けることができるタイプの多型。型理論は型システムの研究です。整数や文字列などの一部のプログラミング言語の具体的なタイプは、コンピュータアーキテクチャ、コンパイラの実装、および言語設計の実際的な問題によって異なります。

基礎
正式には、型理論は型システムを研究します。プログラミング言語には、コンパイル時または実行時、手動で注釈を付けるか、自動的に推測するかにかかわらず、型システムを使用して型チェックを行う機会が必要です。マークManasseは簡潔にそれを置く:
型理論が取り組む根本的な問題は、プログラムに意味があることを確認することです。型理論によって引き起こされる根本的な問題は、意味のあるプログラムがそれらに帰する意味を持たないかもしれないということです。より豊かな型システムの探求は、この緊張から生じます。
タイピングと呼ばれるデータ型を割り当てると、メモリ内の値や変数などのオブジェクトなどのビットのシーケンスに意味が与えられます。汎用コンピュータのハードウェアは、たとえばメモリアドレスと命令コード、または文字、整数、浮動小数点数などを区別できません。これは、可能な値のいずれも本質的に区別されないためです。ビットのシーケンスはを意味する場合がビットのシーケンスをタイプに関連付けると、その意味がプログラム可能なハードウェアに伝達され、そのハードウェアといくつかのプログラムで構成されるシンボリックシステムが形成されます。
プログラムは、各値を少なくとも1つの特定のタイプに関連付けますが、1つの値が多くのサブタイプに関連付けられることもオブジェクト、モジュール、通信チャネル、依存関係などの他のエンティティは、タイプに関連付けられるようになる可能性がタイプでさえ、タイプに関連付けられるようになる可能性が型システムの実装は、理論的には、データ型(値の型)、クラス(オブジェクトの型)、および種類(型の型、またはメタ型)と呼ばれるIDを関連付けることができます。これらは、システムに含まれるレベルの階層で、タイピングが通過できる抽象化です。
プログラミング言語がより精巧な型システムを進化させると、基本的な型チェックよりもきめ細かいルールセットが得られますが、型推論(およびその他のプロパティ)が決定不能になり、より注意を払う必要がある場合は、代償が伴います。プログラマーは、コードに注釈を付けたり、コンピューター関連の操作や機能を検討したりします。型安全な方法ですべてのプログラミング手法を満たす十分に表現力のある型システムを見つけることは困難です。
コンパイラーによって課される型制限が多いほど、プログラミング言語はより強く型付けされます。強く型付けされた言語では、暗黙の変換が害を及ぼさない状況で、プログラマーが明示的な変換を行う必要があることがよくPascalの型システムは、たとえば、配列または文字列のサイズがその型の一部であり、一部のプログラミングタスクを困難にするため、「強すぎる」と説明されています。 Haskellも強く型付けされていますが、その型は自動的に推測されるため、明示的な変換は不要なことがよく
プログラミング言語コンパイラは、依存型またはエフェクトシステムを実装することもできます。これにより、さらに多くのプログラム仕様を型チェッカーで検証できます。単純な値型のペアを超えて、コードの仮想「領域」は、何が何で行われているかを記述し、たとえばエラーレポートを「スロー」できるようにする「効果」コンポーネントに関連付けられます。したがって、シンボリックシステムはタイプアンドエフェクトシステムである可能性があり、タイプチェックのみの場合よりも安全性チェックが多くなります。
コンパイラーによって自動化されているか、プログラマーによって指定されているかにかかわらず、型システムは、型システムの規則の範囲外である場合、プログラムの動作を違法にします。プログラマー指定の型システムによって提供される利点は次のとおりです。
抽象化(またはモジュール性)–タイプを使用すると、プログラマーは、低レベルの実装に煩わされることなく、ビットまたはバイトよりも高いレベルで考えることができます。たとえば、プログラマーは、文字列を単なるバイトの配列ではなく、文字値のセットと見なし始めることができます。さらに高いことに、タイプを使用すると、プログラマーは任意のサイズの2つのサブシステム間のインターフェースについて考えて表現することができます。これにより、より多くのレベルのローカリゼーションが可能になり、サブシステムの相互運用性に必要な定義が、これら2つのサブシステムが通信するときに一貫性を保つようになります。
ドキュメント–より表現力豊かな型システムでは、型はプログラマーの意図を明確にするドキュメントの形式として機能します。たとえば、プログラマーが関数をタイムスタンプ型を返すものとして宣言する場合、これは、タイムスタンプ型がコードのより深いところで整数型であると明示的に宣言できる場合の関数を文書化します。
コンパイラー指定の型システムによって提供される利点は次のとおりです。
最適化–静的型チェックは有用なコンパイル時情報を提供する場合がたとえば、型で値が4バイトの倍数でメモリ内で整列する必要がある場合、コンパイラはより効率的なマシン命令を使用できる可能性が
安全性–型システムにより、コンパイラーは無意味または無効なコードを検出できます。たとえば3 / “Hello, World”、ルールで整数を文字列で除算する方法が指定されていない場合、式を無効として識別できます。強い型付けはより安全性を提供しますが、完全な型の安全性を保証することはできません。

タイプエラー
タイプエラーは、プログラム開発の複数の段階で現れる可能性のある意図しない状態です。したがって、型システムにはエラーを検出するための機能が必要です。型推論が自動化されているHaskellなどの一部の言語では、エラーの検出を支援するために、コンパイラーがlintを使用できる場合が
型の安全性はプログラムの正当性に貢献しますが、型チェック自体を決定不可能な問題にするという犠牲を払ってのみ、正確性を保証する可能性が自動型チェックを備えた型システムでは、プログラムが正しく実行されないことが判明しても、コンパイラエラーは発生しない場合がゼロ除算は安全ではなく誤った操作ですが、コンパイル時に実行されるタイプチェッカーは、ほとんどの言語でゼロ除算をスキャンしないため、ランタイムエラーとして残ります。これらの欠陥がないことを証明するために、プログラム分析と総称される他の種類の形式手法が一般的に使用されています。あるいは、依存型言語などの十分に表現力のある型システムは、これらの種類のエラーを防ぐことができます(たとえば、ゼロ以外の数値の型を表現する)。さらに、ソフトウェアテストは、タイプチェッカーが検出できないエラーを見つけるための経験的な方法です。

タイプチェック
タイプの制約を検証および適用するプロセス(タイプチェック)は、コンパイル時(静的チェック)または実行時に発生する可能性が言語仕様がその型付け規則を強く要求する場合(つまり、情報を失わない自動型変換のみを多かれ少なかれ許可する場合)、プロセスを強く型付けされたものとして、そうでない場合は弱く型付けされたものとして参照できます。これらの用語は通常、厳密な意味で使用されることはありません。

静的型チェック
静的型チェックは、プログラムのテキスト(ソースコード)の分析に基づいて、プログラムの型の安全性を検証するプロセスです。プログラムが静的型チェッカーに合格した場合、プログラムはすべての可能な入力に対して型安全性のプロパティのセットを満たすことが保証されます。
静的型チェックは、プログラム検証の限定された形式と見なすことができ(型安全性を参照)、型安全言語では、最適化と見なすこともできます。コンパイラーがプログラムが適切に型指定されていることを証明できる場合、動的な安全性チェックを発行する必要がないため、コンパイルされたバイナリーをより高速に、より小さく実行できます。
チューリング完全言語の静的型チェックは本質的に保守的です。つまり、型システムが健全(すべての誤ったプログラムを拒否することを意味する)であり、決定可能(プログラムが適切に型付けされているかどうかを判断するアルゴリズムを記述できることを意味する)である場合、それは不完全である必要があります(正しいプログラムであり、ランタイムエラーが発生していなくても拒否されます)。たとえば、次のコードを含むプログラムについて考えてみます。
if then else
がtrue実行時に常に評価される場合でも、静的アナライザーがelse分岐が行われないことを判断することは(不可能ではないにしても)困難であるため、ほとんどの型チェッカーはプログラムを不正な型として拒否します。したがって、静的型チェッカーは、めったに使用されないコードパスの型エラーをすばやく検出します。静的タイプチェックがないと、100%カバレッジのコードカバレッジテストでも、そのようなタイプエラーを見つけることができない場合が値が作成されるすべての場所と特定の値が使用されるすべての場所の組み合わせを考慮に入れる必要があるため、テストではこのようなタイプエラーを検出できない場合が
ダウンキャストなど、多くの便利で一般的なプログラミング言語機能を静的にチェックすることはできません。したがって、多くの言語には静的型と動的型の両方のチェックが静的型チェッカーはそれが何ができるかを検証し、動的チェックは残りを検証します。
静的型チェックを備えた多くの言語は、型チェッカーをバイパスする方法を提供します。一部の言語では、プログラマーは静的型と動的型の安全性を選択できます。たとえば、C#は、静的に型付けされた変数と動的に型付けされた変数を区別します。前者の使用は静的にチェックされますが、後者の使用は動的にチェックされます。他の言語では、タイプセーフではないコードを書くことができます。たとえば、Cでは、プログラマーは同じサイズの任意の2つの型の間で値を自由にキャストでき、型の概念を効果的に覆すことができます。
静的型チェックを使用する言語のリストについては、静的型付き言語のカテゴリーを参照して

動的型チェックと実行時型情報
参照:
動的プログラミング言語と 動的型チェックは、実行時にプログラムの型安全性を検証するプロセスです。動的に型チェックされる言語の実装は、通常、各ランタイムオブジェクトを、その型情報を含む型タグ(つまり、型への参照)に関連付けます。この実行時型情報(RTTI)は、動的ディスパッチ、遅延バインディング、ダウンキャスト、リフレクション、および同様の機能を実装するためにも使用できます。
ほとんどのタイプセーフ言語には、静的タイプチェッカーもある場合でも、何らかの形式の動的タイプチェックが含まれています。 この理由は、多くの有用な機能やプロパティを静的に検証することが困難または不可能であるためです。たとえば、プログラムがAとBの2つのタイプを定義するとします。ここで、BはAのサブタイプです。プログラムがタイプAの値をタイプBに変換しようとする場合、これはダウンキャストと呼ばれ、操作は有効です。変換される値が実際にタイプBの値である場合。したがって、操作が安全であることを確認するために動的チェックが必要です。この要件は、ダウンキャストに対する批判の1つです。
定義上、動的型チェックにより、実行時にプログラムが失敗する可能性が一部のプログラミング言語では、これらの障害を予測して回復することが可能です。その他の場合、タイプチェックエラーは致命的と見なされます。
静的型チェックを含まない動的型チェックを含むプログラミング言語は、「動的型付けプログラミング言語」と呼ばれることがよくこのような言語のリストについては、動的型付けプログラミング言語のカテゴリーを参照して

静的型チェックと動的型チェックの組み合わせ
一部の言語では、静的型付けと動的型付けの両方が可能です。たとえば、Javaやその他の表面上静的に型付けされた言語は、サブタイプへの型のダウンキャストをサポートし、オブジェクトにクエリを実行して、実行時型情報に依存する動的型やその他の型操作を検出します。別の例はC ++ RTTIです。より一般的には、ほとんどのプログラミング言語には、非交和、ランタイムポリモーフィズム、バリアントタイプなど、さまざまな「種類」のデータをディスパッチするためのメカニズムが含まれています。型注釈や型チェックを操作しない場合でも、このようなメカニズムは動的型付けの実装と実質的に同じです。静的型付けと動的型付けの間の相互作用の詳細については、プログラミング言語を参照して
オブジェクト指向言語のオブジェクトは通常、静的ターゲットタイプ(またはマニフェストタイプ)がオブジェクトのランタイムタイプ(その潜在タイプ)またはそのスーパータイプのいずれかに等しい参照によってアクセスされます。これは、特定のタイプのインスタンスで実行されるすべての操作をサブタイプのインスタンスでも実行できるというリスコフの置換原則に準拠しています。この概念は、包摂またはサブタイプ多型としても知られています。一部の言語では、サブタイプはそれぞれ共変または反変の戻り型と引数型を持っている場合が
Clojure、Common Lisp、Cythonなどの特定の言語は、デフォルトで動的に型チェックされますが、オプションの注釈を提供することにより、プログラムが静的型チェックを選択できるようにします。このようなヒントを使用する理由の1つは、プログラムのクリティカルセクションのパフォーマンスを最適化することです。これは、漸進的型付けによって形式化されます。プログラミング環境DrRacket、Lispに基づく教育環境、および言語Racketの前身もソフトタイプです。
逆に、バージョン4.0の時点では、C#言語は、変数を静的に型チェックしてはならないことを示す方法を提供します。型がdynamic静的型チェックの対象とならない変数。代わりに、プログラムは実行時型情報に依存して、変数の使用方法を決定します。
錆、タイプの動的型付け提供タイプ。std::any’static

実際の静的および動的型チェック
静的型付けと動的型付けのどちらを選択するかには、特定のトレードオフが必要です。
静的型付けは、コンパイル時に型エラーを確実に検出できるため、提供されるプログラムの信頼性が向上します。ただし、プログラマーは、型エラーがどの程度一般的に発生するかについて意見が分かれており、設計された型をコードで適切に表現することで検出される、コード化されたバグの割合についてさらに意見が分かれます。 静的型付けの支持者動的型付けの支持者信頼できることが証明されている分散コードと小さなバグデータベースを指します。型システムの強度が増すにつれて、静的型付けの価値は高まります。依存型の支持者、 Dependent MLやEpigramなどの言語で実装されているため、プログラムで使用される型がプログラマーによって適切に宣言されているか、コンパイラーによって正しく推測されている場合、ほとんどすべてのバグが型エラーと見なされる可能性が
静的型付けは通常、より高速に実行されるコンパイル済みコードになります。コンパイラーは、使用されている正確なデータ型(宣言または推論による静的検証に必要)を知っている場合、最適化されたマシンコードを生成できます。Common Lispなどの一部の動的型付け言語では、この理由から、最適化のためにオプションの型宣言を使用できます。
対照的に、動的型付けにより、コンパイラーはより高速に実行され、インタープリターは新しいコードを動的にロードできます。動的型付けされた言語でソースコードを変更すると、実行するチェックが少なくなり、再訪するコードが少なくなる可能性があるためです。これも編集-コンパイル-テスト-デバッグのサイクルを短縮する可能性が
型推論がない静的型付け言語(バージョン10より前のCやJavaなど)では、プログラマーがメソッドまたは関数が使用する必要のある型を宣言する必要がこれは、静的ではなくアクティブで動的な追加のプログラムドキュメントとして機能します。これにより、コンパイラーは、同期から外れたり、プログラマーに無視されたりするのを防ぐことができます。ただし、言語は型宣言を必要とせずに静的に型付けできます(例には、Haskell、Scala、OCaml、F#、および程度は少ないがC#とC ++が含まれます)。したがって、明示的な型宣言は、すべての言語での静的型付けに必要な要件ではありません。
動的型付けにより、一部の(単純な)静的型チェックが不正として拒否する構造が可能になります。たとえば、任意のデータをコードとして実行するeval関数が可能になります。evalの関数は静的型付けで可能ですが、高度な用途必要と代数的データ型を。さらに、動的型付けは、完全なデータ構造の代わりにプレースホルダーデータ構造(モックオブジェクト)を透過的に使用できるようにするなど、移行コードとプロトタイピングにより適しています(通常は実験とテストの目的で)。
動的型付けでは通常、ダックタイピングが可能です(これにより、コードの再利用が容易になります)。静的型付けを使用する多くの言語は、ダック型付けやジェネリックプログラミングなどの他のメカニズムも備えており、コードの再利用も容易になります。
動的型付けは通常、メタプログラミングを使いやすくします。例えば、C ++テンプレートは、典型的には同等以上の書き込みに対してより面倒であるルビーやPythonのためのコードC ++は、(関数と変数の両方について)型定義に関する強いルールを有します。これにより、開発者は、Python開発者が必要とするよりも多くの定型コードをテンプレートに書き込む必要がメタクラスやイントロスペクションなどのより高度なランタイム構造は、静的に型付けされた言語で使用するのが難しいことがよく一部の言語では、このような機能を使用して、実行時データに基づいて新しいタイプや動作をオンザフライで生成することもできます。このような高度な構造は、多くの場合、動的プログラミング言語によって提供されます。これらの多くは動的に型付けされますが、動的型付けは動的プログラミング言語に関連している必要はありません。

強い型と弱い型システム
強いタイピングと弱いタイピング
言語は、口語的に強い型または弱い型と呼ばれることがよく実際、これらの用語が何を意味するかについて、広く受け入れられている定義はありません。一般に、人々がそれらを「強い」または「弱い」と呼ぶように導く型システム間の違いを表すためのより正確な用語が

タイプの安全性とメモリの安全性
型安全性
プログラミング言語の型システムを分類する3番目の方法は、型指定された操作と変換の安全性によるものです。コンピューター科学者は、型安全言語という用語を使用して、型システムの規則に違反する操作や変換を許可しない言語を説明します。
コンピュータ科学者は、メモリセーフ言語(または単にセーフ言語)という用語を使用して、プログラムが使用に割り当てられていないメモリにアクセスすることを許可しない言語を説明します。たとえば、メモリセーフな言語は、配列の境界をチェックするか、配列の境界外への配列アクセスがコンパイル時および場合によっては実行時エラーを引き起こすことを静的に(つまり、実行前のコンパイル時に)保証します。
タイプセーフとメモリセーフの両方を備えた言語の次のプログラムについて考えてみます。
var x:= 5; var y:= “37”; var z:= x + y;
この例では、変数zの値は42になります。これはプログラマーが予期したものではないかもしれませんが、明確に定義された結果です。場合はy別の文字列、数値(例えば、「Hello World」の)に変換することができなかったものをした、その結果はよくとして明確に定義されただろう。プログラムはタイプセーフまたはメモリセーフであり、無効な操作でクラッシュする可能性があることに注意してこれは、型システムが十分に進んでおらず、すべての可能なオペランドに対する演算の有効性を正確に指定できない言語向けです。しかし、プログラムがタイプセーフではない操作に遭遇した場合、プログラムを終了することが唯一の選択肢であることがよく
ここで、Cの同様の例を考えてみましょう。
int x = 5 ; char y [] = “37” ; char * z = x + y ; printf (”%c n ” 、* z );
この例では、5文字を超えるメモリアドレスを指します。これは、が指す文字列の終了ゼロ文字の後の3文字に相当します。これは、プログラムがアクセスすることを期待されていないメモリです。ガベージデータが含まれている可能性があり、確かに有用なものは含まれこの例が示すように、Cはメモリセーフでもタイプセーフでもありません。zyy
一般に、型安全性とメモリ安全性は密接に関係しています。たとえば、ポインタ演算と数値からポインタへの変換(Cなど)をサポートする言語は、任意のメモリに任意のタイプの有効なメモリであるかのようにアクセスできるため、メモリセーフでもタイプセーフでもありません。
詳細については、メモリの安全性を参照して

可変レベルの型チェック
一部の言語では、さまざまなレベルのチェックをさまざまなコード領域に適用できます。例は次のとおりです。
JavaScript およびPerlのuse strictディレクティブは、より強力なチェックを適用します。
declare(strict_types=1)でPHP 型宣言の正確な種類の唯一の変数が受け入れられるか、または可能にするファイル単位でTypeErrorスローされます。
Option Strict OnでVB.NETには、コンパイラはオブジェクト間の変換を必要とすることができます。
lintやIBMRational Purifyなどの追加ツールを使用して、より高いレベルの厳密性を実現することもできます。

オプション型システム
主にGiladBrachaによって、型システムの選択は言語の選択とは独立して行われるます。型システムは、必要に応じて言語にプラグインできるモジュールである必要が彼はこれが有利であると信じています。なぜなら、彼が必須型システムと呼んでいるものは、言語の表現力を低下させ、コードをより脆弱にするからです。型システムが言語のセマンティクスに影響を与えないという要件を満たすことは困難です。
オプション型付けは漸進的型付けに関連していますが、漸進的型付けとは異なります。両方の型付け分野を使用してコードの静的分析を実行できますが(静的型付け)、オプションの型システムは実行時に型の安全性を強制しません(動的型付け)。

ポリモーフィズムとタイプ
ポリモーフィズム(コンピューターサイエンス)
ポリモーフィズムという用語は、コード(特に、関数またはクラス)が複数の型の値に作用する能力、または同じデータ構造の異なるインスタンスが異なる型の要素を含む能力を指します。ポリモーフィズムを許可する型システムは、通常、コードの再利用の可能性を高めるためにそうします。ポリモーフィズムのある言語では、プログラマーは、リストや連想配列などのデータ構造を、タイプごとに1回ではなく、1回だけ実装する必要が彼らがそれを使用することを計画している要素。このため、コンピューターサイエンティストは、特定の形式のポリモーフィズムジェネリックプログラミングの使用を呼び出すことがポリモーフィズムの型理論の基礎は、抽象化、モジュール性、および(場合によっては)サブタイピングの基礎と密接に関連しています。

特殊型システム
特定のタイプのデータを使用する特定の環境での使用、または帯域外の静的プログラム分析に特化した多くのタイプのシステムが作成されています。多くの場合、これらは形式型理論からのアイデアに基づいており、プロトタイプ研究システムの一部としてのみ利用可能です。
次の表は、特殊な型システムで使用される型理論の概念の概要を示しています。名前M、N、Oは、用語と名前にまたがっています
σ τ
{ sigma、 tau}

 タイプの範囲。表記 τ [ α
:=σ ]
{ tau [ alpha:= sigma]}

  (または τ { tau }

 )は、τ内の型変数α(または項変数x)のすべての出現を型σ(または項N)で置き換えた結果として生じる型を記述します。
タイプの概念 表記 意味
関数σ τ
{ sigma to tau}
  Mにタイプがある場合σ τ
{ sigma to tau}
 そしてNは型有しσ次に、アプリケーションを (( )。
{M(N)}
 タイプτです。
製品 σ ×× τ { sigma times tau}
  Mにタイプがある場合 σ ×× τ { sigma times tau}
 、 それから =(( 、 O )。
{M =(N、O)}
 は、NのタイプがσでOのタイプがτであるようなペアです。和 σ + τ
{ sigma + tau}
  Mにタイプがある場合σ + τ
{ sigma + tau}
 、次にどちらか = 1(( )。
{M = iota _ {1}(N)}
 Nがタイプσであるような最初の注入である、または = ι 2(( )。
{M = iota _ {2}(N)}

 Nがタイプτを持つような2番目の注入です。
交差点σ ∩ τ
{ sigma cap tau}
  Mにタイプがある場合σ ∩ τ
{ sigma cap tau}
 、Mのタイプはσ、Mのタイプはτです。
連合σ ∪ τ
{ sigma cup tau}
  Mにタイプがある場合σ ∪ τ
{ sigma cup tau}
 、MはタイプσまたはMはタイプτです。
記録
⟨ :τ ⟩
{ langle x: tau rangle}
  Mにタイプがある場合
⟨ :τ ⟩
{ langle x: tau rangle}
 、Mには、タイプτのメンバーxが
多形 ∀ α τ
{ forall alpha。 tau}
  Mにタイプがある場合 ∀ α τ
{ forall alpha。 tau}
 、Mはタイプ τ [ α
:=σ ]
{ tau [ alpha:= sigma]}
 任意のタイプσに対して。
実存的 ∃ α τ
{ examples alpha。 tau}
  Mにタイプがある場合 ∃ α τ
{ examples alpha。 tau}
 、Mはタイプ τ [ α
:=σ ]
{ tau [ alpha:= sigma]}
 あるタイプのσの場合。
再帰的 μ α τ
{ mu alpha。 tau}
  Mにタイプがある場合 μ α τ
{ mu alpha。 tau}
 、Mはタイプ τ [ α
:= μ α τ ] { tau [ alpha:= mu alpha。 tau]}
 。
依存関数(( : σ )。 τ { displaystyle(x: sigma) to tau}
  Mにタイプがある場合(( : σ )。 τ { displaystyle(x: sigma) to tau}
 そしてNは型有しσ次に、アプリケーションを (( )。
{M(N)}
  タイプがあります τ { tau }
 。
依存製品(( : σ )。
×× τ { displaystyle(x: sigma) times tau}
  Mにタイプがある場合(( : σ )。
×× τ { displaystyle(x: sigma) times tau}
 、 それから =(( 、 O )。
{M =(N、O)}
 ようなペアであるNが型有しσはとOは、タイプを有しています τ { tau }
 。
従属交差点(( : σ )。∩ τ
{ displaystyle(x: sigma) cap tau}
  Mにタイプがある場合(( : σ )。∩ τ
{ displaystyle(x: sigma) cap tau}
 、Mはタイプσ、Mはタイプ τ { tau }
 。
家族の交差点
⋂ :σ τ
{ bigcap _ {x: sigma} tau}
  Mにタイプがある場合
⋂ :σ τ
{ bigcap _ {x: sigma} tau}
 、Mはタイプ τ { tau }
 タイプσの任意の項Nに対して。
家族組合
⋃ :σ τ
{ bigcup _ {x: sigma} tau}
  Mにタイプがある場合
⋃ :σ τ
{ bigcup _ {x: sigma} tau}
 、Mはタイプ τ { tau }
 タイプσのある項Nに対して。

依存型
依存型
依存型は、スカラーまたは値を使用して他の値の型をより正確に記述するという考えに基づいています。例えば、私 (( 3 3 )。 { mathrm {matrix}(3,3)}

  のタイプかもしれません 3 ×× 3 {3 times 3}

 マトリックス。次に、行列の乗算に関する次のルールなどの入力ルールを定義できます。私 u
l I l y :私(( k
、 )。
××私(( 、 )。
私(( k
、 )。
{ mathrm {matrix} _ { mathrm {multiply}}: mathrm {matrix}(k、m) times mathrm {matrix}(m、n) to mathrm {matrix}(k、n )}
  ここで、k、m、nは任意の正の整数値です。この型システムに基づいて、依存型MLと呼ばれるMLのバリアントが作成されましたが、従来の依存型の型チェックは決定不可能であるため、それらを使用するすべてのプログラムが何らかの制限なしに型チェックできるわけではありません。依存MLは、プレスバーガー算術に決定できる等式の種類を制限します。
エピグラムなどの他の言語では、言語内のすべての式の値を決定可能にして、型チェックを決定可能にすることができます。ただし、一般に、決定可能性の証明は決定不可能であるため、多くのプログラムでは、非常に重要な手書きの注釈が必要です。これは開発プロセスを妨げるため、多くの言語実装は、この条件を無効にするオプションの形で簡単な方法を提供します。ただし、これには、タイプチェックを行わないプログラムがフィードされたときにタイプチェッカーを無限ループで実行するという犠牲が伴い、コンパイルが失敗します。

線形型
線形タイプ
線形論理の理論に基づいており、一意性タイプと密接に関連している線形タイプは、常に1つだけの参照を持つという特性を持つ値に割り当てられたタイプです。これらは、ファイルや文字列などの大きな不変値を記述するのに役立ちます。線形オブジェクトを破棄し、同様のオブジェクト( ‘ str= str + “”a””‘など)を同時に作成する操作は、「内部」で最適化できるためです。場所の突然変異。通常、これは不可能です。そのような変更は、オブジェクトへの他の参照を保持しているプログラムの一部に副作用を引き起こし、参照透過性に違反する可能性があるためです。これらは、プロセス間通信のプロトタイプオペレーティングシステムSingularityでも使用され、競合状態を防ぐためにプロセスが共有メモリ内のオブジェクトを共有できないようにします。クリーン言語(Haskellの様言語)は、安全なまま(ディープ・コピーを実行するに比べて)の速度の多くを得るために、このタイプのシステムを使用しています。

交差型
交差型
交差型は、値セットが重複している他の2つの特定の型の両方に属する値を表す型です。たとえば、Cのほとんどの実装では、signed charの範囲は-128〜127で、unsigned charの範囲は0〜255であるため、これら2つのタイプの交差タイプの範囲は0〜127になります。このような交差タイプは安全に渡すことができます。両方のタイプと互換性があるため、signedまたはunsigned文字のいずれかを期待する関数に。
交差型は、オーバーロードされた関数型を記述するのに役立ちます。たとえば、「 」が整数引数を取り、整数を返す関数の型であり、「 」がfloat引数を取り、floatを返す関数の型である場合、これらの2つのタイプの共通部分を使用して、与えられた入力のタイプに基づいて、どちらか一方を実行する関数を記述することができます。このような関数は、「 」関数を安全に期待する別の関数に渡すことができます。単に「 」機能を使用しません。intintfloatfloatintintfloatfloat
サブクラス化階層では、型と祖先型(その親など)の共通部分が最も派生した型です。兄弟タイプの共通部分は空です。
Forsythe言語には、交差型の一般的な実装が含まれています。制限された形式は、改良タイプです。

共用体タイプ
共用体タイプ
共用体型は、2つの型のいずれかに属する値を記述する型です。たとえば、Cでは、signed charの範囲は-128〜127であり、unsigned charの範囲は0〜255であるため、これら2つのタイプの和集合は、全体的な「仮想」範囲が-128〜255になります。アクセスされるユニオンメンバーに応じて部分的に使用されます。この共用体型を処理する関数は、この完全な範囲の整数を処理する必要がより一般的には、共用体タイプで有効な操作は、結合されている両方のタイプで有効な演算のみです。Cの「共用体」の概念は、共用体型に似ていますが、両方ではなくどちらかの型で有効な操作を許可するため、型セーフではありません。共用体型は、プログラム分析で重要です。共用体型は、正確な性質(値や型など)が不明なシンボリック値を表すために使用されます。
サブクラス化階層では、型と祖先型(その親など)の和集合が祖先型です。兄弟タイプの共用体は、共通の祖先のサブタイプです(つまり、共通の祖先で許可されているすべての操作は、共用体タイプで許可されますが、他の有効な操作も共通している場合があります)。

存在型
存在記号
存在型は、実装をインターフェースから分離できるため、モジュールおよび抽象データ型を表すためにレコード型に関連して頻繁に使用されます。例えば、タイプ「T = {∃X:X; F:(XINT);}」という名前のデータメンバ有するモジュールインターフェース記述するタイプのXおよび機能命名Fのパラメータを取り同じタイプXで、整数を返します。これはさまざまな方法で実装できます。例えば:
intT = {a:int; f:(intint); }
floatT = {a:float; f:(floatint); }
これらの型は両方とも、より一般的な存在型Tのサブ型であり、具体的な実装型に対応します。したがって、これらの型のいずれかの値は、型Tの値です。型「T」の値「t」が与えられると、「 tf(ta) “”は、抽象型Xが何であるかに関係なく、適切に型指定されています。これにより、特定の実装に適したタイプを柔軟に選択できますが、インターフェイスタイプ(既存のタイプ)の値のみを使用するクライアントは、これらの選択から分離されます。
一般に、タイプチェッカーが特定のモジュールが属する既存のタイプを推測することは不可能です。上記の例では、intT {a:int; f:(intint); }は、タイプ∃X{a:X; f:(intint); }。最も簡単な解決策は、すべてのモジュールに目的のタイプで注釈を付けることです。例:
intT = {a:int; f:(intint); }として∃X{:X。f:(Xint); }
抽象データ型とモジュールはかなり前からプログラミング言語で実装されていましたが、ジョンC.ミッチェルとゴードンプロトキンが「抽象型には存在型がある」というスローガンの下で正式な理論を確立したのは1988年のことでした。理論は、システムFに似た2次型付きラムダ計算ですが、全称記号ではなく実存的定量化を使用しています。

漸進的型付け
漸進的型付け
漸進的型付けは、コンパイル時(静的型付け)または実行時(動的型付け)のいずれかで変数に型を割り当てることができる型システムであり、ソフトウェア開発者は内部から必要に応じていずれかの型パラダイムを選択できます。単一の言語。特に、漸進的型付けは、動的という名前の特別な型を使用して静的に未知の型を表し、漸進的型付けは、型の同等性の概念を、動的型を他のすべての型に関連付ける一貫性と呼ばれる新しい関係に置き換えます。整合性の関係は対称的ですが、推移的ではありません。

明示的または暗黙的な宣言と推論
型推論
CやJavaなどの多くの静的型システムでは、型宣言が必要です。プログラマーは、各変数を特定の型に明示的に関連付ける必要がHaskellのような他のものは、型推論を実行します。コンパイラーは、プログラマーがそれらの変数をどのように使用するかに基づいて、変数の型について結論を導き出します。たとえば、加算と加算を行う関数が与えられた場合、コンパイラはそれを推測でき、数値である必要が加算は数値に対してのみ定義されているためです。したがって、引数として非数値型(文字列やリストなど)を指定するプログラムの他の場所への呼び出しは、エラーを通知します。f(x, y)xyxyf
コード内の数値および文字列の定数と式は、特定のコンテキストでの型を意味する場合が例えば、発現は、3.14のタイプを意味するものかもしれない浮動小数点ながら、整数、典型的のリストを意味するものかもしれない配列。
問題の型システムで計算可能であれば、型推論は一般的に可能です。さらに、特定の型システムで一般に推論が計算できない場合でも、実際のプログラムの大部分で推論が可能であることがよくHindley–MilnerのバージョンであるHaskellの型システムは、型推論が計算可能な、いわゆるランク1ポリモーフィック型へのシステムFωの制限です。ほとんどのHaskellコンパイラは、拡張機能として任意のランクのポリモーフィズムを許可しますが、これにより型推論が計算できなくなります。(ただし、型チェックは決定可能ですが、ランク1のプログラムには型推論が明示的な型注釈が与えられていない限り、上位のポリモーフィックプログラムは拒否されます。)

決定問題
型理論§決定問題
型規則を使用して型環境の用語に型を割り当てる型システムは、当然、型チェック、型付け可能性、および型居住の決定問題に関連付けられています。
与えられたタイプの環境 Γ { Gamma}

 、 用語 e {e}

 、およびタイプ τ { tau}

 、用語かどうかを決定します e {e}

  タイプを割り当てることができます τ { tau}

  タイプ環境で。 e {e}
 、型環境が存在するかどうかを判断します Γ { Gamma}

  とタイプ τ { tau}

  そのような用語 e {e}

  タイプを割り当てることができます τ { tau}

  タイプ環境で Γ { Gamma}

 。
与えられたタイプの環境 Γ { Gamma}

  とタイプ τ { tau}

 、用語が存在するかどうかを判断します e {e}

  タイプを割り当てることができます τ { tau}

  タイプ環境で。

統一型システム
C#やScalaなどの一部の言語には、統一された型システムがこれは、プリミティブ型を含むすべてのC#型が単一のルートオブジェクトから継承することを意味します。C#のすべての型は、Objectクラスから継承します。JavaやRakuなどの一部の言語には、ルート型がありますが、オブジェクトではないプリミティブ型も Javaは、プリミティブ型と一緒に存在するラッパーオブジェクト型を提供するため、開発者はラッパーオブジェクト型またはより単純な非オブジェクトプリミティブ型のいずれかを使用できます。Rakuは、メソッドにアクセスすると、プリミティブ型をオブジェクトに自動的に変換します。

互換性:同等性とサブタイピング
静的型付け言語の型チェッカーは、いずれかの種類のことを確認する必要があります式は、その式が現れる文脈によって期待されるタイプと一致しています。たとえば、形式の代入ステートメントでは、式の推定型は、変数の宣言型または推定型と一致している必要が互換性と呼ばれるこの一貫性の概念は、各プログラミング言語に固有のものです。x := eex
のタイプeとのタイプxが同じであり、そのタイプに割り当てが許可されている場合、これは有効な式です。したがって、最も単純な型システムでは、2つの型に互換性があるかどうかの問題は、それらが等しい(または同等である)かどうかの問題になります。ただし、言語が異なれば、2つの型式が同じ型を表すと理解される場合の基準も異なります。これらの異なる等式理論タイプのは、二つの極端なケースがある、広く変化構造型システムと同じ構造を有する値を記述する任意の二つのタイプが同等である、、、および主格型システムどの2つの構文的に異なるタイプの表現は、同じタイプを示していないれました、(つまり、型が等しくなるためには、同じ「名前」が必要です)。
サブタイプのある言語では、互換性の関係はより複雑です。特に、Bがのサブタイプである場合、その逆が真でない場合でも、タイプのA値は、タイプのB1つAが期待されるコンテキスト(共変)で使用できます。同等性と同様に、サブタイプの関係はプログラミング言語ごとに異なる方法で定義され、多くのバリエーションが可能です。言語にパラメトリックまたはアドホック多相が存在することも、型の互換性に影響を与える可能性が

も参照してください
icon
 コンピュータプログラミングポータル
タイプシステムの比較
共変性と反変性(コンピューターサイエンス)
オブジェクト指向プログラミングにおけるポリモーフィズム
タイプルール
型注釈
型理論

ノート
^ バローズALGOLコンピュータラインはフラグビットによってメモリ位置の内容を決定しました。フラグビットは、メモリ位置の内容を指定します。命令、データ型、および機能は、48ビットの内容に加えて3ビットのコードで指定されます。MCP(マスター制御プログラム)のみがフラグコードビットに書き込むことができました。

参考文献
^ Pierce 2002、p。1:「型システムは、計算する値の種類に従ってフレーズを分類することにより、特定のプログラムの動作がないことを証明するための扱いやすい構文方法です。」
^ Cardelli 2004、p。1:「型システムの基本的な目的は、プログラムの実行中に実行エラーが発生しないようにすることです。」
^ Pierce 2002、p。208。
^ タイソン、JR(1983年4月25日)。「JRTは彼が有罪だと言っています—使用可能なパスカルを作成したことについて」。Infoworld。5(1)。NS。66。
^ カーニハン、ブライアン(1981)。「なぜPascalが私のお気に入りのプログラミング言語ではないのか」。2012年4月6日にオリジナルからアーカイブされました。
^ 「…音の決定可能な型システムは不完全でなければなりません」—D。レミー(2017)。NS。29、 レミー、ディディエ。「プログラミング言語の型システム」(PDF)。検索された26 5月2013。
^ ピアス2002。
^ Gaurav Miglani、Gaurav(2018)。「Javaでの動的メソッドディスパッチまたはランタイムポリモーフィズム」。アーカイブされたオリジナルの2020年12月7日に。2021-03-28を取得。
^ ライト、アンドリューK.(1995)。実用的なソフトタイピング(PhD)。ライス大学。hdl:1911/16900。
^ “”動的(C#リファレンス)””。MSDNライブラリ。Microsoft 。
^ “”std :: any —Rust””。doc.rust-lang.org 。2021-07-07を取得。
^ マイヤー、エリック; ドレイトン、ピーター。「可能な場合は静的型付け、必要な場合は動的型付け:プログラミング言語間の冷戦の終結」(PDF)。マイクロソフトコーポレーション。
^ ラウチャー、アマンダ; ちなみに、ポール(2012)。「タイプとテスト」。InfoQ。
^ Xi、Hongwei(1998)。実用的なプログラミング(PhD)の依存型。カーネギーメロン大学数理科学部。CiteSeerX 10.1.1.41.548。
Xi、Hongwei; Pfenning、Frank(1999)。「実用的なプログラミングにおける依存型」。プログラミング言語の原理に関する第26回ACMSIGPLAN-SIGACTシンポジウムの議事録。ACM。pp。214–227。CiteSeerX  10.1.1.69.2042。土井:10.1145 /292540.292560。ISBN 1581130953。S2CID  245490。
^ Visual Basicは、タイプセーフとメモリセーフの両方を備えた言語の例です。
^ 「4.2.2ECMAScriptの厳密なバリアント」。ECMAScript®2020言語仕様(第11版)。ECMA。2020年6月。ECMA-262。
^ 「厳密モード–JavaScript」。MDN。Developer.mozilla.org。2013-07-03 。
^ 「厳密モード(JavaScript)」。MSDN。Microsoft 。
^ 「厳密な型付け」。PHPマニュアル:言語リファレンス:関数。
^ Bracha、G。「PluggableTypes」(PDF)。
^ 「もちろんです。これは「漸進的型付け」と呼ばれ、流行と見なします。…」静的型付けと動的型付けの両方を可能にする言語はありますか?。スタックオーバーフロー。2012年。
^ Kopylov、Alexei(2003)。「依存交差:型理論でレコードを定義する新しい方法」。コンピュータサイエンスにおける論理に関する第18回IEEEシンポジウム。LICS2003。IEEEComputerSociety。pp。86–95。CiteSeerX 10.1.1.89.4223。土井:10.1109 /LICS.2003.1210048。
^ ミッチェル、ジョンC。; プロトキン、ゴードンD.(1988年7月)。「抽象型には存在型がある」(PDF)。ACMTrans。プログラム。ラング。Syst。10(3):470–502。土井:10.1145 /44501.45065。S2CID 1222153。  
^ ジーク、ジェレミー(2014年3月24日)。「漸進的型付けとは何ですか?」。
^ ジーク、ジェレミー; タハ、ワリド。関数型言語の漸進的型付け(PDF)。スキームと関数型プログラミング2006。シカゴ大学。pp。81–92。
^ バレンドレッグ、ヘンク; デッカーズ、ウィル; スタットマン、リチャード(2013年6月20日)。タイプのラムダ計算。ケンブリッジ大学出版局。NS。66. ISBN
 978-0-521-76614-2。
^ 「8.2.4型システムの統合」。C#言語仕様(第5版)。ECMA。2017年12月。ECMA-334。
^ 「ネイティブタイプ」。Perl6ドキュメント。
^ 「数値、§オートボクシング」。Perl6ドキュメント。

参考文献
カーデリ、ルカ; ウェグナー、ピーター(1985年12月)。「タイプ、データ抽象化、およびポリモーフィズムの理解について」 (PDF)。ACMコンピューティング調査。17(4):471–523。CiteSeerX  10.1.1.117.695。土井:10.1145 /6041.6042。S2CID  2921816。
ピアス、ベンジャミンC.(2002)。タイプとプログラミング言語。MITプレス。ISBN 978-0-262-16209-8。
カーデリ、ルカ(2004)。「型システム」 (PDF)。アレン・B・タッカー(編)。コンピュータサイエンスとエンジニアリングのCRCハンドブック(第2版)。CRCプレス。ISBN 978-1584883609。
トラット、ローレンス。「5.動的型付け言語」。コンピュータの進歩。77。エルゼビア。pp。149–184。土井:10.1016 / S0065-2458(09)01205-4。ISBN 978-0-12-374812-6。

外部リンク
ウィキブックスのAdaプログラミングには、次のトピックに関するページがタイプ
ウィキブックスのHaskellには、次のトピックに関するページがクラス宣言
image
 コモンズの型システムに関連するメディア
スミス、クリス(2011)。「型システムについて議論する前に知っておくべきこと」。”