関数型ガチ勢から見たScalaのアンチパターン

Scalazのコミッター、もしくはScalazを使いこなしているような関数型ガチ勢からみると、ある程度以下の様な共通認識*1がある気がする(けどあまり知られていない?)ので、ちょっとまとめてみました。

関数型ガチ勢ではない一般のScalaユーザーの間では、あまり疑問も持たずにそれなりに使われているものが多い気がします

個人的には、以下で紹介するものを「絶対使うな」とも思いません。*2が、しかしこれらのものに対して「アンチパターンとは言わないけど、デメリット多いし代替手段あるよね」という意見の人が少なすぎる気がするし、もうちょっとその辺りの議論がされるべきではないかなぁーと思い、あえて「アンチパターン」と言ってみました。

タイトルにScalaを入れましたが、厳密にはScalaに限らない話だと思います。ただし、「JVMで動く静的型付き関数型言語」という状況により、ある程度Scala特有の状況な気もします。言い換えると「JVMなのでリフレクションが使える、かつ他の言語由来の色々な関数型のテクニックも使える言語」という似たような状況は、それほどないので。*3


  • リフレクション
    • 静的型付き言語としての機能が十分強力なら、リフレクションより常に良い代替があるということだと思う。*4 (どこまで本気なのかわからないが)よくtonymorrisさんは「JVMがtype erasureにしたのは正しい」とまで言っている。リフレクションで実行時に取得した型情報にプログラムが依存するべきではない→「実行時に詳細な型情報が取れる必要ない、むしろ取れないほうが正しい」という理屈だろう。ゆえに、リフレクション使った以下の様なものは全部アンチパターンである(?)
  • リフレクション使ったDependency Injection
  • リフレクション使ったシリアライズ、デシリアライズ
    • 型クラス使え?
  • リフレクション使って、JSONとcase classの相互変換
  • リフレクション使ってマッピングを行うOR Mapper
  • リフレクション使って実行時にアノテーションを読み取って、色々やり過ぎる仕組み
  • リフレクションつかったmockオブジェクト作成のフレームワーク
    • 綺麗に構造化できてない、プログラムが小さい部品に分かれてなくてComposableじゃないので、そんなものが必要になるのでは?
  • implicit paramaterを型クラスとして使わずに、環境を引き回すために使う
    • Reader Monadとか使え?


他にもっと似たようなものがあった気がするのだけど、思い出せないので、思い出したらあとで追記する

*1:twitter上やメーリングリストで、こういう意見を見かけた、という意味。けど、全部の出典をそれぞれ調べて載せるのは面倒だったのでサボりました。すいません

*2:Javaのテクニックも使いつつ、徐々に関数型に慣れることが可能な点が、Scalaの良さでもありますからね・・・

*3: F# などで、同じようなこと言われていたりしないのだろうか?

*4:まぁ、ホントにガチな人は、「リフレクションなんて絶対に使うな」という感じだと思うけど

*5:cake patternが嫌いな人も結構いたり、そもそもcake patternがアンチパターン http://togetter.com/li/539827 といった話までありましたが