型付け
「強い型付け」「弱い型付け」はどこらへんに境目があるのか
まず「静的型付け」や「動的型付け」といった言葉はエンジニアリング上の意味を持っている。
「静的型付け」というのは実行前に型が決まることだし、「動的型付け」は実行時に型が決まることで、だいたいの書籍で同じようなことが書いてあると思う。
しかし「強い」とか「弱い」といった言葉はどうにも不確実な言い回しだ。
「美味い牛丼」とか「不味い牛丼」とか言われたときと同じような「いやそれアンタの主観だろ」的なモヤっとした感じがする。
一般的に、暗黙的キャストを許さない言語は「強い型付け」、キャストを明示しなくても暗黙的にキャストする言語は「弱い型付け」となるのだろうが、「いったいどの程度から強いと言えるのよ」という疑問がなかなか消えてくれない。
その境目はどこなのだろうか。
例えばJavaScriptとPHPでは、
この2つの言語は「弱い動的型付け」とされていて、簡単に異なる型同士の演算を許してくれるが、その結果はまったく違う。
JavaScriptは文字列型として結合するが、PHPは数値型として演算する。
なぜかというと、JavaScriptは+演算子が加算と文字列連結子両方で使用されるのに対し、PHPは+演算子は加算のみ(文字列連結子はドット)で使用されるためだ。
だが、この2つのうち「どちらのほうが弱いのか」と問われても、どう答えれば良いのか分からない。
では「強い動的型付け」であるRubyではどうなるか。
整数型から文字列型への暗黙キャストはできないと叱られる。
このように簡単には暗黙キャストしてくれない言語は「強い型付け」だと言われる。
静的型付けであるCとC++ではどうだろうか。
WikipediaにはCは「弱い静的型付け」、C++は「強い静的型付け」と記されている。
どちらも結果は同じで、暗黙キャストしてくれる。
しかし、以下のようにポインタ変数の場合は違う。
Cはvoid*をint*へ暗黙キャストするが、C++はそれを許容しない。
ここらへんが「C++は強い型付け」だと言われる根拠なのだろう。
ではJavaだとどうなるだろう。
Javaは「強い静的型付け」とされている。
意外にもCと同じく暗黙キャストして演算してくる。
なるほど、それならば文字列型と数値型ならば拒絶するに違いない。
しれっと文字列型として結合してきた。
もう何をもって「強い型付け」なのか分からなくなってきた。
同じく「強い静的型付け」とされるGoやRustはどうだろうか。
異なる型同士の演算はまったく受け付けない。
この結果ならたしかに「強い型付け」だと感じられる。
C++もJavaもGoもRustも、「強い型付け」の言語とされているようだが、GoやRustから見るとC++やJavaの型付けは弱いようだ。
これらをすべて同じ「強い型付け」と表して良いのかどうか。
GoとRustは「とても強い型付け」、C++とJavaは「やや強い型付け」、Cは「やや弱い型付け」、JavaScriptやPHPは「とても弱い型付け」となるのだろうか。
そもそも人の主観が含まれる表現なので、「いやいや、最近はPHPのほうがCよりも少し強い型付けになってきた」という人がいるかもしれないし、「そんなことはない」と誰かが反論したところで、それもその人の主観なので「どちらが強いのか」に結論は出そうにない。
ちなみに私自身、型付けに「強さ」という概念はあるような気はしている。
JavaScriptよりもRubyのほうが「強い」感じがするし、RustよりもCのほうが「弱い」感じがするのは確かなのだ。
ただ「どこから強いと言えるのか」とか「何をもって強いと言えるのか」となると、よく分からなくなる。
強さというのは程度の問題なので、「中くらいの型付け」というのがあっても不思議ではないのだが、そういった言葉を見かけることはない。
正直、CとJavaの型付けの強さが「弱い」と「強い」に分かれる根拠もよく見えなかったが、今回の検証でさらに見えなくなってきた。
そんなこんなで「強い型付け」「弱い型付け」の境目を探し出そうとしてみたが、結局分からなかった。
その言語の型付けが「強い」のか「弱い」のかは、他の言語と比べてどうなのかということ、またそれすらも人の主観だということだ。
技術的な定義としての「強い型付け」「弱い型付け」というものは存在できないなと感じた一件だ。
|