関数型言語でのTDDについての妄想
OOPの言語(自分がやっているのはPHP)でプログラムを書く場合、TDD(テスト駆動開発)を愚直に実践しています。
この話は、関数型言語を使うようになったら、開発プロセスがどのように変わるのだろうかという妄想です。
最近、『関数型ドメインモデリング』の関数型言語のF#でのアプリケーションの作り方を見て、ドメインの仕様を型レベルで定義していくというのが興味深く感じました。確かに型レベルで仕様が定義することができると、コンパイル時にチェックされるので、ランタイム時に望まない状態になることが不可能になるため、より早い段階で間違いが検出できるというのは大きな利点だと感じました。
ここで、疑問が出てきました。型レベルで仕様を定義する開発プロセスでは、今まで実施してきたようなOOP言語のTDDによる開発のプロセスを適応できるんだろうか。別のより適切な開発プロセスがあるんだろうか。と疑問に思いました。
OOP言語のTDDでやっていることは、ドメインについての自分の仕様理解をテストで表現して、それを最低限満たす実装をするというのを繰り返すことです。型の表現力が関数型言語と比較して高くないため、仕様を主にオブジェクトのランタイム時の動作として想定することで、それをテストとして表現しています。
一方、型レベルで仕様を定義する開発プロセスでは、一番最初の段階でテストが書けないんじゃないかと心配になりました。最初に、型で仕様を定義するフェーズが入って、その後実装をするフェーズになってからTDDをすることになるのかなと想像しました。
ここまで書いてきて、別に最初に型で守られる範囲の定義も、TDDで行なえばいいだけですね。ただし、ドメインの振る舞いも含めて型を定義した後は、望まない状態が発生しないことがコンパイル時点で保証されるため、そのテストを残す価値がなくなるので、そのテストは開発を駆動したけど、不要になって削除されるべきテストとなる、程度の影響なのではないかと考えました。妄想では、関数型言語でも同様にTDDで開発を進めることができそうだという結論です。
ここまで妄想してきましたが、実際に、F#等でTDDをしてみればいいのです。試してみたいです。