理想のプログラミング言語と副作用

副作用

最近思うに,プログラミングの「副作用」という用語は結構ミスリーディングだ.

確かに副作用を持つコードはバグの温床になりやすいと言うしその実感もあるけど,じゃあ副作用なんてやめて全部主作用にしよう,全部引数と戻り値に書いちゃおう,とはならない. それはおそらく,ある程度大きいプログラムになってくるとすべての情報のやり取りを明示的に書くのが面倒だし,読む方も大変だからだ.

その辺「副作用」なら暗黙的に事を済ませられるのでありがたい. つまり,それは薬の副作用と違って,扱いにくいけれど必要なものだ.

PythonHaskell

ところで,オブジェクト指向や関数型といったプログラミングパラダイムは副作用をストレスフリーに扱うための技術とみなすこともできる.

例えば,オブジェクト指向的なPythonでは関数の代わりにメソッドを利用する.このときオブジェクト指向によれば,副作用のスコープを各メソッドの紐付くオブジェクト(self)内に限定しなければならない.こうすることで副作用の及ぶ範囲がコントロールされ,バグの特定が簡単になったりする.

一方,純粋関数型言語と呼ばれるHaskellでは,副作用を明示的に表現する. と言っても,ただ副作用の情報をどこかにベタ書きするのではなく(それでは副作用の暗黙性が失われてしまう),副作用の種類に応じて用意されているモナドを利用する*1.これによって,すべての副作用は暗黙的でありながらコンパイラのチェックを受けることができるので,バグが減る.

こんな観点から眺めると,2つの対立させられがちなパラダイムが目指す共通の方向性が見えてくる気がする.

理想のプログラミング言語

やっと本題に入るわけだが,個人的な理想のプログラミング言語の要件として, ストレスフリーに副作用を扱えること,というのがある. 上に挙げたPythonHaskellは自分が触ったことのある範囲で一位二位を争う好きな言語だが, どちらにしてもまだ惜しいところがあると思う.

HaskellからPythonを見ると,スコープ以外無差別に副作用を扱おうというのはちょっと無謀だし,コードを読む側やドキュメントをメンテするコストもバカにならない.最近はtypingモジュールも導入されて型検査はしやすくなっているが,副作用の型付けにはまだ程遠そうに思われる.

一方で,PythonからHaskellを見ると,モナドという何でもできる型クラスの担当範囲が節操なく,節操ないがゆえに一つのことをやるのに二つ以上の書き方ができてしまう(一番単純には全部IOでいいじゃん的なやり方を許してしまう)ことがHaskellの書き味・読み味にオーバーヘッドを生んでいる気がする*2

おそらく自分はPythonicなコードの書き方が好きだけど,Haskellの純粋さも欲しいという人間なのだ. そんな自分は,頻出モナドを仕様レベルでサポートしてくれるようなプログラミング言語がほしいと思ってしまう.

*1:自分で作ることもできるが,ライブラリ開発者でなければ普通はやらない気がする.

*2:言語仕様のコンパクトさはHaskellの美点の一つなので,コンパクトゆえ書き方に自由度が残るのは仕方のないことでもあると思う.