441. 結局、型が必要なんじゃないか!〜動的型付けの裏切り〜
どうも、みなさん。Pythonが大っ嫌いな筆者です。
最近、現場でPythonのコードを書かされるたびに、頭を抱える問題があります。それは、「型」、です。
「え? Pythonは動的型付けで、C++やJavaみたいに型宣言しなくていいから楽チンなんでしょ?」
って、世間の人は言いますよね。私も昔はそう思っていました。
P子「で、結局、楽じゃなかったんでしょ」
ご名答。全く楽じゃありませんでした。型がない、なんてのは幻想です。正確には、「実行してみるまで型がわからない」という、恐ろしい爆弾を抱え込んでいるだけなんです!
開発時の「イライラ」
Pythonが初心者に優しいとか言われるのは、型宣言を省略できるからでしょう。
Python
# 楽ちん(に見える)なPythonのコード
data = 100
data = "Hello"
しかし、これが大規模なシステムや、他人が書いたコード、あるいは半年後に自分が読み返すコードになると、地獄と化します。
「この関数、x に何を入れたらいいんだ?」
関数の定義を見ただけでは、xが整数(int)なのか、文字列(str)なのか、あるいは複雑なリストや辞書(list, dict)なのか、さっぱりわかりません。ドキュメントを読め? ソースコードを追え?
P子「それがエンジニアの仕事でしょ」
そうですけど! 静的型付け言語なら、IDEが教えてくれるか、コンパイラが怒ってくれます。Pythonは実行時まで何も言ってくれない。
そして、やってくるのがあの瞬間です。
TypeError: unsupported operand type(s) for +: 'int' and 'str'
ええ、ええ、わかってますよ。私のミスです。でも、型を宣言しなくていいって言ったのは誰だ! 「型がない」から楽、じゃなくて、「型を気にしなくていい瞬間だけがある」だけなんだと、私は声を大にして言いたい!
型ヒントという名の「敗北宣言」
あまりにも型にまつわる事故が多いので、Pythonには**型ヒント(Type Hinting)**という機能が導入されました。
Python
# 型ヒントを導入したコード
def add_data(x: int, y: int) -> int:
return x + y
見ろ! この醜い姿を!
「型がないのが魅力!」だったはずなのに、結局はC++やJavaと同じように型を記述しているじゃないですか!
P子「結局、その方が便利だった、ってことじゃないの?」
その通りです。便利なんです。開発効率が上がるし、バグも減ります。
しかし、これは同時にPythonが「動的型付けだけでは大規模開発の現実から逃れられない」と敗北を宣言したようなものだと、私は思うんです。最初から型付け言語として生まれていれば、こんな二度手間は必要なかったでしょうに!
しかも、型ヒントはあくまで「ヒント」。処理速度に関係なく、実行時チェックではないので、コードがヒント通りに使われているかは実行前にMyPyなどの外部ツールでチェックしなければならない。
面倒くさい!
型チェックの仕組みは言語に組み込んでおくべきだろ! なんで外部ツールに頼らなきゃならないんだ!
まとめ
Pythonを使うたびに感じるのは、「最初から型の概念を嫌うべきではなかった」という、開発者の浅はかさです。
型を自由に扱える楽しさは認めます。しかし、その「自由」は、常にランタイムエラーという名の死の宣告と隣り合わせ。そして、その危険から逃れるために、結局「型ヒント」というツギハギを使う羽目になっている。
「結局、型が必要なんじゃないか!」
Pythonは、この根本的な矛盾を抱えたまま、初心者にもプロにも「優しくない」言語であり続けていると、私は思うのです。
P子「今回もすごい悪口ね。でも、その『醜い』型ヒントのおかげで、あなたの書いたコードが読みやすくなったのは事実でしょ」
ぐっ...返す言葉もありません。それがまた、釈然としない理由の一つなんです。チクショー!
次回も、Pythonの嫌いなところを探して、たっぷりと愚痴らせていただきます。さようなら。