愚かなハッカーたれ、利口なエンジニアよりも

地方でフリーでプログラミングスキルで生きていく

まだ動的型付け言語で消耗してるの?

最近、Swift、Kotlin、Goでプログラムを書いていますが、だんだんRubyのような動的型付け言語で開発するのは精神的に辛くなってきたと感じる今日このごろ。

アプリ開発はiOSObjective-CAndroidJavaで、最初からコンパイルありきの静的型付け言語での開発が前提だった。これらの言語は今見れば古臭く洗練されているとは言いがたい。回りくどい書き方を強要され、プログラミングを書くコストは高かった。それに比べるとサーバーサイドの開発は、Ruby + Railsで楽で良いという印象だった。

しかし、SwiftやKotlinの登場により状況は変わった。非常に書きやすくなり、アプリ開発でプログラムを書くコストはかなり下がった。そして、相対的にウェブアプリをRuby + Railsで書くことのコストを高く感じるようになったのだ。

まず、苦痛なのは構文エラーや未定義の変数・メソッドとの戦い。実行してそのコードの実行を試みるまでわからない。だから、

  • 実行
  • 未定義エラー(たいていタイポだが)
  • 修正
  • 実行

のサイクルを繰り返すことになる。だからきちんとテストを書けということなのだろうが、静的型付け言語よりもテストを書くコストが上乗せされているように感じるのは気のせいだろうか?おじさんプログラマには時間がないから、テストはロジカルにクリティカルなところに絞りたいのだ。

静的型付け言語ならコンパイルすれば、構文エラー、未定義エラーは自動検出&複数一括で表示してくれる。あとはまとめてバリバリ取るだけだ。そして実行できる段階では、これらのエラーは無いことが保証されている。今さらながら、こういったことがありがたく思えてきた。

それにやっぱり変数も厳密に型定義を必要とする方がいい。これはコストではない。むしろ変数になんでも入る動的型付け言語の方に書くコストがあると思う。数値だと思ったら文字列だったり、文字列かと思ったらシンボルだったり。そして、to_iしたりto_sしたり。

メソッドの引数にどんな型が渡されるかわからないから、コメントに引数の型が何であるべきか書いたり、意図しない型が渡ってきたら例外を投げたりする。不毛な作業である。静的型付け言語ならメソッドを宣言する時に型定義するから、それらを書く必要はない。

そして何より困るのがリファクタリングである。プログラムはある程度の規模になったら、リファクタリングしたくなるものだ。私はクラスやメソッドの名前が気に食わなくなって変更することはしょっちゅうある。

KotlinやGoならIDEリファクタリング機能を使えば、確実に間違いなく名前変更できる。同名の変数やクラスがあっても別物は別と判別してくれ、意図しないところが書き換わったりしない。Xcodeは現状、Swiftのリファクタリング機能はないが、それでも名前変更をしたら、古い名前で参照してる箇所はコンパイルエラーとなるから確実に修正できる。

動的型付け言語だとこうはいかない。エディタで単なるテキスト置換しようものなら、実体が異なる同名変数や同名クラスも置換してしまう。だから1つずつ間違わないように見ていかなければならない。

名前を変えるだけなら、そこまで苦労はないが、クラス設計を大きく変える時は大変だ。静的型付け言語ならリファクタリングの途中でコンパイラがエラーを吐きまくるかもしれないが、逆に言うとコンパイラが手伝ってくれているのだ。

これに対してコンパイラの助けがない動的型付け言語では、プログラマが最高レベルにまで精神統一してリファクタリングに励む必要がある。シナプスがところどころ断線しているおじさんプログラマに無茶は言わないで欲しい。

学習コストの低さと手軽に書ける利便性。しかし、規模が大きくなるにつれ、その利便性を取ったことへの代償が大きくなっていく。最近、動的型付け言語に対して、そんな風に思うようになってきた。SwiftやKotlinはとても書きやすく、モダンな静的型付け言語は従来のそれと動的型付け言語にあった壁を崩したように思う。そして改めて静的型付け言語の堅牢さが身に沁みるのである。

そんなことを思った1年前。サーバーサイドも静的型付け言語で行こうと、1つの開発でGoを選んだ。確かにRailsに比べると至れり尽くせりではない。しかしそれなりの規模になった今、リファクタリングをする時に、静的型付け言語のGoを選んで良かったと思える。

でもやっぱり例外は欲しい・・・Scalaのが良かったのかな・・・。Rubyはツールスクリプト書くのに今も重宝してます。