このBlogは移転しました。今後は aish.dev を御覧ください。

動的型言語の使いどころ

型宣言というのは良い物だ。型が明確なら、実行速度は型情報がない場合と比べて100倍も200倍も高速になるし、エラーチェックだってできる。リファクタリングも簡単だ。

型がないほうがいいという人は、昔の、まだプロトタイプ宣言がなかった頃のCコンパイラでも使ってみるといい。静的型チェックの有り難みが身にしみることだろう。型宣言を書くのがめんどくさいったって、大したことはない。さすがにC++の型宣言はめんどくさかったが、autodecltype のおかげで楽になった。それでもめんどくさいというなら、Fortranでも使って i ではじまる変数名は宣言不要とか言って喜んでるといい。「暗黒の型宣言」とか言い換えて中二病気分を満喫するのもいいだろう。

しかし、動的な型システムの言語というのも、それはそれで良い物だ。現在、私の主力言語はPythonであり、そのメリットは日々実感している。動的型システムを使った開発スタイルのほうが、静的型システムを使った開発スタイルよりも私の目的には適しているからだ。

アプリケーション開発という面から見た時の、動的型言語のメリットとはなんだろうか。色々とあるが、システム開発全体のライフサイクルへ与える影響を考えると、「不具合のあるアプリケーションを実行できる」ということだと思っている。「そんなアプリ実行しねーよ」と思うかもしれないが、そんなことはない。開発中・修正中のアプリは全て不具合のあるアプリで、この期間中、我々はアプリをだましだまし実行しながら開発・デバッグを進めているのだ。動的型言語をつかうなら、この「だましだまし」のだましやすさを意識し、最大限に活用しなければ意味が無い。

昔からよく言われるプログラミングの格言に、こんなのがある -

「Make it work, Make it right, Make it fast - in that order.」

とりあえずでも何でも、まずはなによりも動くコードを書き、次にそのコードが正しく動くようにする。最後に、パフォーマンス上の問題があれば、適正な時間内に処理できるようにする。「動かす・正しく・速く」と、この順番が重要だ。正しい処理があいまいなうちにコードを最適化しても意味が無いし、正しくないコードでも、動かないコードよりははるかにマシだからだ。

動的型言語は、このスタイルの開発に素晴らしくマッチする。書きやすいところ、書きたいところ、気になってるところなどを気ままに書き散らし、実行して思考内容を実験できる。「Make it work」のステップを、段違いに素早くすすめられるのだ。このメリットを活かせば、ものすごいスピードで実装と実行を繰り返してアプリケーションドメインと問題点を正しく理解し、最終的には「正しい」実装にまでたどり着ける。開発手法としては、トップダウンというよりボトムアップなアプローチに適しているだろう。

もちろん、デメリットもある。「Make it work」が効率的でも、「Make it right」のステップでは不利な面もある。静的型システムならコンパイル時に検出できるエラーもでも、動的型システムだと動かしてみないとわからない。しかし、このような型チェックで検出できるのは、かなり単純なエラーだけで、単純な関数の引数間違いなど、うっかり見逃して本番環境で出してしまうと、背中が汗でびしょびしょになるようなやつだけだ。こういったエラーは単体テストを流すだけでほとんど検出できるし、動的言語ではテストを書くコストが安くつくので、単体テストカバレッジ100%近くを目指すのもそんなに難しいわけではない。動的型言語でも静的型言語でもテストを書く必要性は変わらないわけで、ここは大きな問題ではないと考えている。

ただ、リファクタリングツールなどでコードの自動修正などを行うのは難しいし、静的にコードを解析してコード補完を行うことも難しい。もしPythonが静的な型システムを持っていたら、Python2->3の移行はあっという間に完了したことだろうw。パフォーマンス面の不利はもちろんあるし、JITを使っても万能ではなく、JITのコストでかえって負荷が増大する場合もある。単純に変数の宣言がないから素晴らしいとか、そんな単純な話ではないのである。