型システム:名義対構造、明示対暗黙


24

名義型システムと構造型システムの違いについて少し混乱しています。誰かが彼らがどのように違うのか説明してもらえますか?

私が理解していることから:

  • 名義:型の互換性は型名に基づいています。
  • 構造:型の互換性は型構造に基づきます。たとえば、Cでは、2つの変数が異なる名前で同じ構造の構造体型である場合、それらの型は互換性があります。

ここで、明示的および暗黙的について:静的および動的型付けと異なるのはなぜですか?静的型付けでは型は明示的ですが、動的型付けでは型は暗黙的です。私は正しいですか?

回答:


29

動的に型付けされたシステムでは、値には実行時に型がありますが、変数と関数にはありません。静的に型付けされたシステムでは、変数と関数には既知の型があり、コンパイル時にチェックされます。たとえば、Pythonのx場合は何でもかまいません。実行時に、それが1数値である場合、それが"foo"である場合、文字列です。x実行時にどのタイプかがわかるだけで、プログラムを実行するたびに異なる可能性があります。Javaのような言語では、数字であるint xかどうかを記述xし、コンパイル時にx常にそれが必要であることがわかりますint

「明示的な」および「暗黙的な」型は両方とも静的型システムを指します。静的システムの特徴は、コンパイル時に型がわかっていることですが、必ずしも書き出す必要はありません。Javaでは、型は明示的です-型を記述する必要があります。したがって、Javaでは、メソッドは次のようになります。

public int foo(String bar, Object baz) { ... }

タイプは、コンパイル時(静的)書き出された(明示的)両方で知られています。ただし、型の記述を強制しない言語もあります。関数の種類とその使用方法から、関数のタイプを推測できます。例はOCamlで、次のように書くことができます。

let foo x = x + 1

あなたが使用しているので+、OCamlのは、その把握することができxなければならないintすべては自分自身で。だから、の種類foofoo : int -> int)がされただけでJavaの例のように、コンパイル時に知られています。完全に静的です。ただし、コンパイラーは型が独自に必要なものを把握できるため、自分で型を記述する必要はありません。それらは暗黙的です。

つまり、型システムが明示的であるか暗黙的であるかは、静的システムの特性です。型システムが動的か静的かはまったく別の質問です。

多くの場合、明示的である場合と暗黙的である場合がある型システムがあります。

たとえば、C#ではvarキーワードを使用して型を推測できると考えています。だからではなく、書き込みのint x = 10、あなたが書くことができvar x = 10、そのうちのコンパイラ数字はxなければなりませんint。C ++はと同様のことを行いautoます。これらのシステムは通常明示的ですが、ある程度の推論があります。

反対に、通常は暗黙的ですが、場合によってはタイプシグネチャの記述を強制するシステムがあります。Haskellは素晴らしい例です。ほとんどの場合、Haskellはタイプを推測できます。ただし、show . readHaskellが独自に型を判別できない場合のように、あいまいなコードを作成できる場合があります。この場合、showまたはのいずれかのタイプを明示的に指定する必要がありますread。さらに、型システムのいくつかのより高度な機能(ランクnポリモーフィズムなど)により、推論が決定不能になります。つまり、停止が保証されません。つまり、この機能を使用するコードには、明示的な型シグネチャが必要になることがよくあります。


2
実際、明示的な動的型付けと呼ぶことができる言語がいくつかあります。一般的に、これらの言語は、あなたがタイプと表現に注釈を付けることができ、その後、それらの型がチェックされます実行時に対して実行時の型表現の。
ヨルグWミットタグ

正確さ:型システムは暗黙的または明示的ではありません。これは型推論に関するものです。これは本質的に、異なる(場合によっては指定されていない)構文から型システムで有効な用語を生成する方法です。
エドゥアルドパレハトベス

良い答えですが、これは名義型と構造型の両方に対応していません。編集は素晴らしいでしょう。
lunchmeat317

7
  • 静的と動的は、型がいつチェックされるかを説明します(コンパイル時または実行時に多少なりとも)

  • 2つのタイプが同じであると見なされる場合、名義対構造を記述します。

(バリエーションもありますが、最もよく知られているのは、アヒルタイピングとして知られるタイプ全体の代わりに使用されるもののみを考慮する構造タイピングのバリアントです)。

4つの組み合わせ(静的名義、静的構造、動的名義、動的構造)が可能であり、言語は純粋に1つのクラスではなく、他のクラスにある側面を持っています。

たとえば、C ++の型システムは静的であり、ほとんどが名目ですが、テンプレートを検討する場合は構造的です(また、C ++の概念に関する問題の一部は、アヒルの型付けから完全な構造型付けまで、名目上のタイピングに行きたい人)。また、クラスと継承を使用すると、場合によっては動的な名義型を使用できます。

動的型システムが構造タイピングを使用していることが多い言語ですが、CLOSは名目上の側面です。


1

構造:型の互換性は型構造に基づきます。たとえば、Cでは、2つの変数が異なる名前で同じ構造の構造体型である場合、それらの型は互換性があります。

これは通常そうではありません。構造型指定とBは、のインターフェースをA満たすことができるかどうかのサブタイプですA。これは通常、同じ名前のメンバーを持つことを意味します。メモリ内の同じ構造だけではありません。

これは、宣言時にスーパータイプを指定する必要がある主格型とは異なります。


1

動的型システムと静的型システム(の実際の包含)の違いについて私が見た最も良い説明は、Bob Harperによるこのブログ投稿にあります。

その主なポイントは次のように要約できます。

  • 動的言語は、タイプが1つだけの静的言語です。

1
リンクが悪くなる可能性があります。記事の最も関連性のある部分を引用する必要があります。そうすれば、たとえブログがうまく行かなくても後世のために保持されます。
ドーバル

2
確かに。この場合、私が追加した文で十分だと思います:)
エドゥアルドパレハトベス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.