以下ポエム.

ホント1. Haskellは純粋関数型言語である

せやな

ウソ1. 再帰は分かりやすい

今すぐ関数プログラミング 珠玉のアルゴリズムデザインを買え.そして難しさに絶望しろ! 再帰で書かれていてとても分かりやすいはずだろう?

現実問題として, f x y = f (f (g x) y) y のように関数自身の引数に再帰が出現するパターンだと動作理解は難しいと思います.

また,ループより再帰が分かりやすいというのもたまに見ますが謎な意見です. ループが限定的な再帰であるならば,用途が限定されてるぶん再帰よりも理解も楽です.

ウソ2. IOモナドは素晴らしい

まずは心を落ち着けてJavaの検査例外批判を思い出しましょう.

f がgを呼び,gがhを呼んでる状況で,メモ化のためにhをIOにしたとします. するとgがIO化し,fもIO化していかざるを得なくなることが多々あります. するとapplicativeやなんや使ったとしても結構な量のコード書き換えが発生してしまいつらぽよになります.いやほんとつらぽよなんです.

そもそもIOはモナドじゃなくてEffectの方が良かったんじゃないのかなあ… (Effectよくしらない人間並の感想)

ウソ3. 遅延評価サイコー

遅延評価には,様々な問題があり,サンクコストやリソース開放タイミングの問題という計算機的な問題もありますが, 何よりデバッグとロギングが大変ということを主張したいです. まずprintfデバッグ等々のログ取りが意外と大変で,デバッグ用に仕込んだコードが実行されないことがままあります. 他には遅延評価前提で書いてしまって,ロギングのため正格評価させようとした瞬間プログラムが崩壊したりします.

「全てを」遅延評価にするのってちょっと理想論によりすぎかなぁと思います.(だからこそHaskellは研究用言語として優れているのですが) もちろん遅延シーケンスは大変便利ですし,map, filter, foldが遅延されてないと困りますが.

まぁ,Virtual DOMのような明らかに実行タイミングを好き勝手弄れる方が得するものを遅延評価前提でライブラリを組めるのは 大きなメリットですし,自動並列化の夢を見るためには正格評価なんぞ保証されてない方がいいと思います. もっともっと賢いコンパイラの登場に期待.

そしてClojureのススメ

副作用の扱いについてはClojureが面白い方法を採用してます.refは許すがそこはdosyncで囲めとか面白いでしょう? また,Clojureは正格評価ですが簡単に遅延シーケンスを記述できるため,ある意味遅延評価のいいとこどりができます. 遅延評価を正格評価するのもまま簡単です.ClojureはほんとHaskellに毒されてしまったかたにオススメの言語ですぜ. 静的型付けがデフォルトでは無いのが残念ですがね!!