セキュリティ&プログラミングキャンプ のBoFで、笹田さんがやってたセッションで話したことがある。言語の進化はベストプラクティスの取り込みにある、と。
ベストプラクティス取り込みの歴史
計算可能である事柄を計算するだけが問題であるなら、チューリング完全な言語なら何でも良いということになるし、不完全な言語は出る幕すらない。ラムダ計算からの自然なマップを考えるならS式で書いて何か実行すれば良いんだし、最小のプリミティブから出発するのが目的ならLazy Kなんかもいいかもしれない。
でも、工学的要請からは、計算可能関数が等しく計算の対象となるわけではない。そして、ある種の計算の傾向、パターンに対して「こうすればいい」「こう考えればいい」「こう設計すればいい」というベストプラクティスが生まれてくる。プログラミング言語の歴史を眺めていると、経験の中から立ち現れるベストプラクティスを取り込んだものが多いことに気がつく。
- 構造化
- 例外サポート
- オブジェクト指向
- 並列サポート
言語の進化はベストプラクティスをサポートするためにあるんじゃなかろうか。
私は昔、例外サポートが何のためにあるのか理解できなかった。例外処理ってのはつまりエラー処理で、エラーハンドリングをしっかりやれば良いのだ。それって、言語がコア言語仕様としてサポートするほどのことだろうか。だが、これは分散システムの制御部分をCで、「全部のエラーコードをハンドリングする」という方針で書いてみて分かった。エラーを伝播させるのは真面目にやるととても大変だ。この状況に対する解法として、大域脱出と型のマッチを組み合わせたC++/Javaにあるような例外処理機構はとても良くできている。例外処理は言語がサポートしなくてもできるが、サポートするだけの価値がある。最小主義ならLazy Kに任せておけばいい。
今後の進化
今後メインストリームの言語はどのように進化していくだろうか。きっとそれは、今知られているベストプラクティスを取り込む方向であるに違いない。 例えば並列サポートは明らかに今後のトレンドだ。他にも色々とある。
Ruby
Rubyの言語仕様のうち、C#やJavaの世界から評価されているものを挙げてみよう。
Rubyの nil
は デフォルトのNULLオブジェクト としてNULLオブジェクトパターンをサポートする。
ブロック構文は無名関数の簡易版である。一級市民としての関数というベストプラクティスをサポートしつつ、「一級市民=オブジェクト, 手続き呼び出し=メッセージ送信」というポリシーと何とか折り合いを付けている。
Rubyのクラス定義とmix-inの仕組みは、「多重継承は益よりは害をもたらしがちでオブジェクト指向設計においては無くてもなんとかなる、が、それでも限定的にあれば便利ではある」という経験からの結論だ。
パターンマッチ
また、パターンマッチもある。HaskellやMLにあるようなパターンマッチは何故JavaやC#にないのか。Rubyに至ってはメソッドオーバーロードすらない。Rubyはメッセージセレクタにメソッド名だけを使用するから、引数の数が明らかに異なる場合でも同名のメソッドを持つことができない。代わりにRubyはパターンマッチの不完全なまがい物とでも言うべき柔軟なcase式によってその手の事柄を処理する。
Rubyのようなユーザーが拡張可能なパターン照合機構とHaskellのような文法が合わされば、きっとRubyのcase式のごときものは無用となって、よりメンテナンスしやすいコードの実現に繋がると思うんだけれど。
Noop
そう考えたとき、DIやテストの自動化というのは価値が立証されているベストプラクティスだ。だから、 森崎修司さんの指摘 のように、これらを言語に取り込むのは意味があることに違いない。