型システムの分類
プログラミング言語の型システムの分類としては、下記の3つの軸があるようです。
- 静的な型付け or 動的な型付け
- 弱い型付け or 強い型付け
- 型安全かそうでないか
簡単に調べてみたので、メモしておきます。
静的な型付け or 動的な型付け
静的型付けな言語は、型検査が実行時の式に関する同値性の検査なしに行われます。
プログラムを実行する前に全ての式・変数の型が決まっていて、事前に型検査を行うことができます。
C/C++, Java, Haskellが静的型付けの言語です。
まあ、C/C++やJavaはキャストが出来てしまいますし、ポリモーフィズムなど処理によっては動的な型情報の取得を必要とするものがあるので微妙ですね。
次に、動的型付けな言語ですが、プログラムを実行してからでないと決まらない式がある言語のことです。
変数でなんでも指せるイメージですね。
Lisp, Ruby, Python, JavaScriptなどが動的型付けな言語です。
SmalltalkやRubyなどの動的型付け + オブジェクト指向言語だと、ダック・タイピングなどをよくやりますが、メソッドの引数として入ってくる変数の型が分からないので、ソースが追いづらいと思うのですがどうなんですかね。
まあ、C++やJavaでも、ポリモーフィズムをしている場合はどのインスタンスか分かりづらいこともありますが、少なくともあるクラスを継承してるとか、あるインターフェースを実装してるってところまではわかるので、だいぶ絞られると思います。
弱い型付け or 強い型付け
この分類に関しては、色々な意見がありそうです。
ひとつが、型の暗黙的な変換をする言語は弱く型付けされた言語で、それをしない言語は強く型付けされた言語だというものです。
この分類では、JavaScriptなどは弱く型付けされた言語で、Java, Ruby, Haskellなどは強く型付けされた言語となります。
もうひとつは、型エラーがおこる可能性をすべて検出できる言語が強く型付けされた言語でそうでない言語が弱く型付けされた言語というものです。
この分類では、Javaもキャストの失敗は実行時にしか検出できない場合があるので、弱く型付けされた言語となります。
強く型付けされた言語に当たるのは、HaskellやMLになります。
型安全かそうでないか
型の食い違いによる「意味のない」「正しくない」操作によって誤った状態を引き起こす処理や変換を許さない言語が型安全な言語で、そうでない言語が型安全でない言語と言われています。
この分類も色々意見があるようですね。
Lisp、Ruby、Pythonといった言語は、実行時にエラーを発生させ、実行を止めるので型安全です。
C言語は、不正なキャストができてしまうので型安全ではありません。
Javaだと実行時にキャストエラーがでるので型安全と言えそうですが、ジェネリクスの目的は、「型安全にコレクションを使えるようにする」つまり、「キャストエラーがでなくなるので型安全だ」というようなことも言われているのでよくわからないですね。
あとは、例えば、SQLなどを文字列で表現するとそこにミスがあっても、コンパイル時にエラーを検出できないから、工夫してどうにかソースコードで表現して、おかしかったらコンパイルエラーにするっていうアプローチがあって、それを「型安全にする」と呼んでいるのも聞いたことがあります。