型システム-プログラミング

型システム(type system)とは

型システムとは、プログラミング言語における値や式を「データ型」に分類して、型の扱いを定義する仕様のことです。

型システムについてBenjamin C. Pierceは以下のように定義しています。


(型システムは)プログラムが計算する値の種類に従って句(phrase)を分類することで、
そのプログラムがある動作をしないことを証明する扱いやすい文法的手法である。 

コンピュータにおける全ての値は「ビットの集まり」です。

ハードウェアでは整数、浮動小数点数、文字、メモリアドレス等といったデータの間に区別はありません。

しかし、ビットの集まりに対して「型付け(型を割り当てる)」することで、データとしての意味を与えることができます。

型システムは、コンピュータに対してプログラムのビット列をどのように扱うべきかという情報を与えることができます。


型システムの利点

  • 不正処理の検出
    • 型付けすることで、コンパイラが不正なコードを検出することが可能になります。
    • 例えば、数値は演算可能なデータですが、文字列は演算可能なデータではありません。数値と文字列で演算された場合に、型の違反として不正を検出することができます。
  • コンパイラによる最適化
    • (静的な)型検査を行うことで、コンパイラは最適化するための情報を得ることできます。
    • メモリアドレスの配置情報が分かることで、コンパイラはより効率の良いマシン命令を選択することができます。
  • ソースコードの可読性向上
    • データの型は、プログラマの意図を説明するドキュメントの役割となります。
    • 関数の戻り値が文字列ならば、その関数は文字列に対する処理を行うことを明示します。

型検査(type checking)とは

型検査とは、データ型がプログラミング言語の仕様通りに使用されているかどうか検査することです。

型検査はコンパイラが行う意味解析の一部であり、コンパイル時に行う「静的検査」とプログラム実行時に行う「動的検査」があります。

また、型検査時には、データに型を割り当てる「型付け(typing)」を行う場合もあります。


静的型付け(static typing)

静的型付けとは、コンパイル時に全ての式、関数、変数などの型が決められる言語的特性です。

静的型付け言語では、プログラムの定義時点で処理する対象の型を決定するため、ソースコード上で厳密な記述を要求します。

基本的には、型が異なるデータを受け付けないという原則となります。

JavaやC言語は、静的型付け言語といえます。


動的型付け(dynamic typing)

動的型付けとは、プログラム実行時に全ての式、関数、変数などの型が決められる言語的特性です。

動的型付け言語では、プログラム定義上では型の限定を行わず、実行時にデータを判定して、適切な変換を施したり別の機能に委譲します。

そのため、ソースコード上でデータの型について厳密な記述は必要ありません。

RubyやLispは、動的型付け言語といえます。


強い型付けと弱い型付けについて

強い型付け(Strong typing)

強い型付けとは、プログラミング言語が型の規則を強く適用することです。

データに対して型の互換性を検出し、互換性がなければエラーとしたり、型の強制変換を行います。

JavaやRubyは、強い型付け言語といえます。


弱い型付け(Weak typing)

弱い型付けとは、プログラミング言語が型の規則を強要しないことです。

言語が型の暗黙的な変換(またはキャスト)を行います。

そのため、コンパイラは特定のメモリ位置にあるデータが整数なのか、文字列なのかということを必ずしも意識する必要はなくなります。

アセンブリ言語やC言語は、弱い型付けといえます。


強い型付けと弱い型付けの例

強く型付けされた言語では、以下のコードがコンパイルエラーとなります。

弱く型付けされた言語では、暗黙的に変換を行うため、コンパイルエラーになりません。


var a = 12345;
var b = "6789";
var c = a + b;

強い型付けがされているとコンパイル時にバグを見つけることが容易になりますが、明示的に型変換をする必要があるので、プログラミング時の負担が大きくなります。

弱い型付けの場合は、プログラミング時は負担が軽いですが、コンパイルでバグを検出することが難しくなります。


型推論

型推論とは、静的型付け言語において、変数や関数の型を宣言しなくてもそれを導くのに使われた関数の型シグネチャなどから自動的に型を決定する機構のことです。

例えば、以下のプログラムでは加算という演算によって関数の戻り値が数値であると決定できます。


function(x){
  var rc;
  rc = x + 1;
  return rc;
}

型推論を持つ言語としてはHaskell、ML、C#、Scala、D言語などがあります。


関連ページ