言語機能とリファクタリングの安全

 静的型では思いつくままに型を作る - プログラマーの脳みそで言ったは、Javaのような静的型付けの言語でのプログラミングの際に、型設計を事前に頑張りすぎないことが軽快にプログラミングするコツだということ。

 事前に十分な型設計を行い、プロトタイピングなしで型設計を完成させようという重厚長大なアプローチは、さながらウォーターフォール開発のようなもので、それこそLLを好む人たちが忌み嫌ったやり方だと思う。そして、静的型付け言語だからといって、そのような開発スタイルをするべきではないと思うし、そうしたスタイルを想定して静的型付け言語をdisるのは的外れだと思う。

 静/動の型付けの違いによらず、プログラミングの際にはアルゴリズムとデータ構造を考えなくてはならないわけだけど、このステップはアジャイル開発のようにプロトタイピングをしながら進めていくスタイルがよいと思う。あるプロトタイプから次のプロトタイプへという段でリファクタリングを行おう。そして、リファクタリングを原理的にしやすい言語のほうがこのスパイラルは軽快にできるのではないだろうか。

リファクタリング機械的サポート

 リファクタリングは動作を変えずに実装を改善する作業なわけだけど、適当にやると動作が変わってしまう。変わると言うかバグるというか、動かなくなってしまう。

 リファクタリングのバイブルとされるのはマーチン・ファウラーのリファクタリング―プログラムの体質改善テクニックなのだけど、リファクタリングのカタログには操作手順が明記されている。手作業でのリファクタリング作業は面倒だし、結構な技術力が要求される。それが機械的に安全に行えるというのはとても素晴らしいことだ。

 単純なリファクタリングに、名前の変更があるのだけど「そんなのgrepして一括置換すればいいだけじゃん」と考えていると痛い目を見る。別のクラスの同名のメソッドを一括して置換してしまったり、もっと下手をすれば"set()"を"init()"に変えるのに"setHoge()"も"initHoge()"に変えてしまったりする。僕も昔、秀丸エディタ+javacコマンドで開発する環境下でリファクタリングしようとして何度かやらかした。

 これらの教訓から「動いているコードには触るな」という格言が生まれてくるのだろうけども、コンパイラのごとく構文解析して安全に名前変更を機械処理してくれる時代になった。現代でのクラス名やメソッド名、変数名などのリファクタリングは非常にリスクが低い。

原理的に安全が保証できない部分

 かといってリスクがゼロなわけではない。Javaの場合だとリフレクションまわりの機能など型安全ではない部分と言うのがあって、それにまつわる部分では単純な名称変更といえども機械処理のリファクタリングの後に動作しなくなることがある。

 こうした「機械処理でも原理的に安全を保証できない」という部分が多い言語は、よりリファクタリングがしにくいと言えるだろう。

 id:NyaRuRuによればリファクタリングツールの進化過程として

Smalltalk Refactoring Browser

IntelliJ IDEA → ReSharper

Eclipse

という流れがあるという。"Smalltalk Refactoring Browser"はマーチン・ファウラーの書籍「リファクタリング」でも取り上げられており、歴史は古いと思うのだけど、詳しくは調べれていない。こうした系譜を踏まえて、リファクタリングツールの機能比較をした場合、プログラミング言語間で「原理的に安全」な部分と言うのは違ってくるんじゃないだろうか。

IDEサポートが強力になるかどうかは動的型・静的型かが問題じゃなくて、バイナリに豊富なメタ情報を持ってるかなんじゃね?

という説も出たけども、ソースコードが入手可能な前提においては、メタ情報はソースから取得可能なわけで原理的に保証できる部分はそんなに変わらないんじゃないかな。もちろん、バイナリだけが提供されていて、リンクして使うようなシチュエーションでは「メタ情報がないから無理」は出てくると思う。

 動的型付けで安全が保証できない部分というのは、例を挙げればオブジェクトに動的にメンバを足したり削除したりできる機能性と、そこに絡む部分。メンバの名称の変更ですら、動的追加されるメンバ名と衝突すれば動作しなくなってしまう。

 こうした、各種プログラミング言語の言語機能とリファクタリングの安全度の対応付けを網羅的に調べてみると何か見えてくるのかもしれない。