「動的型付け言語」という表現に抵抗があるので動的言語と呼んでいる話
結論
重箱の隅つつきなので結論から書く
- 「動的型付け」はナンセンス
- 「型なし言語」は通じにくい
- 「動的言語」のほうが短いし無用なミスマッチもなくて良い
- おそらく「型」が指すものが人によって異なる
静的型付けの話
動的言語の話をする前に、「静的型付け」について書く。ここでは「いわゆる典型的な静的型付け言語」の話をする
静的型付けの背景にあると思われる考え
静的型付けの背景には、こういう考えがあると思う:
プログラム中の「変な」式はたいていプログラムの記述ミスである。例えば文字列を整数に代入する操作は何らかの誤りであることが多い。そのような「変な」記述は、実行するまでもなく、コンパイル時にエラーとして報告してくれたほうが「便利」である
もちろん、文字列を整数に代入するのは「変な」式ではないという主張もありうる。例えば文字列から整数への変換を間に挟めば実行はうまくいく可能性がある。そのような式がエラーになるのは「便利」ではない、ともいえる
しかし、少なくとも静的型付け言語の設計において、「変な」式はエラーになってくれたほうが「便利」であるという考えがある、はずだ
静的型付けの仕組みの軽い説明
静的型付けについて軽く説明する
静的型付けは、プログラムの部分式に型を対応させる工程である。そのことによって、プログラムの妥当性の検証と、振る舞いの解析を行う
言語側に型付け規則というルールがあらかじめ定まっている。例えば
42
のような整数リテラルの型はint型である- x, y の型が等しいなら、式
x == y
の型はbool型である if cond {} else {}
の中で、condの型はbool型である
といった規則がある
このような規則を順に適用していき、規則に違反している式を見つけたらエラーにする
ポイントは静的型付けがあくまで構文に対する操作であり、プログラムの実行ではないこと
型は式につく
(たまに誤解されている気がするので書いておくと、) 静的型付けとは「変数」だけに型をつけるだけのことではない。すべての変数、関数、および「式」に型がつく
例えば int x = a + b;
という変数宣言があるとき、xの型がintであることだけでなく、式 a + b
の型がintであることも重要になる
もし a + b
の型がintではなく文字列だったとする。文字列をintに代入するというのは「変な」操作であるため、型エラーにする必要がある。そのために式 a + b
の型が何であるかを計算する必要がある
動的言語の話
一方、動的言語では事情が異なる。ここでも「いわゆる典型的な動的言語」の話をする
動的言語では、コンパイル時に型付けは行わない
値に実行時型情報がにつく
動的言語のランタイムは通常、値と一緒に実行時型情報を持ち運ぶ。実行時型情報は値の種類を表す追加の情報である。JavaScriptでいう typeof
の値のようなもの
a + b
を計算するとき、ランタイムは a, b の値と実行時型情報を参照できる。それに基づいて +
の挙動を変える。演算子のこのような振る舞いはオーバーロードに似ているが、通常の実行の一環である
そういうわけで、動的言語は型付けをしないので、「動的型付け」という表現はナンセンスである
「型なし」
型付けをしないので、型なし (untyped) と表現することも可能である。しかしここまでに書いたような文脈を共有した上でかろうじて通じる表現、という気がする
何を型と呼ぶか
コミュニティによって「型」が指すものが異なる気がする。静的型付け言語のコミュニティでは、静的型付けの工程に出現する「型」のことを型と呼んでいる。一方、動的言語のコミュニティでは「実行時型情報」のことを型と呼ぶ
伝統的に「型」とは静的型付けの文脈での型を指すことと、静的型付け言語で実行時型情報を参照する機会は少ないことから、前者だけを「型」と呼ぶのは自然に思える。一方、動的言語では静的型付けの型を指したいことはないし、実行時型情報を参照する機会が多いので、それを単に型と呼ぶと便利である