Haskell始めて、終わりました。

 Haskell始めました。
 Scalaを使いこなすには(ついでにC++11、boostも)、Haskellを通らないわけにはいかないと言うことで「すごいHaskell楽しく学ぼう」を読んだところです。実際本を買ったのは半年ほど前で、半年かけてゆっくり読み進みました。

 本を読みがてら、ちょろちょろとライブラリとかを見て驚いたのですが、例えば、Qtとか、Gtkとか、MessagePackとか、C++で実績のある重量級のライブラリは既にHaskellに対応していてドキュメントもわりかししっかりしています。WebフレームワークもYesod等まともに動作するとされているのが三種類もあります。

 なんとなく、実用という意味ではOCamlの方が盛り上がっているイメージがあったのですが、そうでもないようです。みなさんF#に流れているのでしょうか。

 しかし、このHaskellと言う言語は興味深いところも多いのですが、じゃ、Toyでもいいから何か作ってみようかと思うとなにも思い浮かびません。ですのでHaskellで身につけた知識をC++ScalaC#に持ち帰って使うというのが正解のように思えます。(実際そうされている方は多いのでは無いのかと思います)
 HaskellPlatformが相当に良い仕事をしているのでもったいないのですけどね。
 Toyと言うとスクリプト的な使い方から始まるわけですが、スクリプトなんて、逐次処理の代表みたいなモノですのでHaskellと相性BADです。じゃ、画像処理の一部をHaskellに置き換えてみようかというと、画像処理なんてmutable処理の塊ですので、さすがにC++でループ書いた方が手早いです。そういう意味では、scalaGUIスクリプティングもなんでもござれで、本当にCの速度が必要な局面以外では使えるのでよくできていると思います。小から大までスケールできる言語という触れ込みは伊達では無いと思います。
 そして、Haskellですが、今時シングルパラダイム言語というのは、使えるシチュエーションが非常に限られるのでやはり厳しいのではないのかなと思います。
 Haskellだとクイックソートが簡潔(5行で)に書けると言われても、そのクイックソートはニセモノ(笑)とか言われるていたらくでどうしようもありません。それにクイックソートを自分で書く機会なんかありませんし、ちょっと意味がわからないなぁという感じです。

 実用という観点では、VCからHaskellを使うには、FFIをdll経由で使うというアクロバティックなことが必要で、デバッグがウルトラ面倒くさそうです。
 典型的なHaskellの用途として、コンパイラと金融関係がよくあげられていますが、私はもちろん、どちらの分野でもありません。そして、Yesodならどうかというのもありますが、WEB屋でも無いのでどうかなと言うところです。
 確かに、関数型プログラミングはいわゆるRESTとは相性良いのは理解できますが、趣味でWEBをやるならScalaのPlay2があるのでわざわざHaskellでやるモチベーションに欠けます。
 関数型のお作法というのは、MVCで言うところのimutableなcontrollerを記述するのに向いているとは思うのですが、viewとdocumetを書くには向いていないように思えます。ですので、viewとdocumetはC++で書いて、controllerはHaskellと言う組み合わせには夢が見られます。
 しかし、そういう使い方をするにはFFIはpoor過ぎると思います。C形式でしかインターフェイスできないのは仕方が無いとしても、VCとスタティックにリンクできないのはいただけません。
 個人的には、シングルパラダイム言語というのは一種のDSLだと思うわけで、他の言語との相互運用性が問われるところだと思います。その点はF#とscalaは非常に柔軟な言語のmixができるので、関数型プログラミングしたいところだけできるのですばらしいと思います。
 しかし、HaskellC++を組み合わせようとすると結局のところtrivial object以外のオブジェクトの受け渡しが大いに面倒くさくなるので二の足を踏んでしまいます。
 となれば、結局、アプリケーションそのものが関数的であるコンパイラHaskellが向いているのもうなずけます。
 そうですね。特許の出願書類の検証ソフトとかを作るには良いかもしれません。

 それと気にくわないのが、Intがいわゆるintで、IntegerがいわゆるBigIntと言うような80年代な命名規則で、個人的にはこういう往年のUnix丸出しは得意ではありません。こういう一貫性の無い命名規則は、毎日10時間つきあい続けるプロエンジニアのためのもので、土日だけつきあうには覚えきれるものではありません(同様の理由でruby vs pythonではpython派です)。
 また、今時、ByteStringがあちらこちらで使われていていてUnicodeではないというのは減点どころではありません。F#やScalaでは当然、内部の文字列は全てUnicodeであるので余計なことに悩まずにコードが書けるのに、ライブラリ内部の知らないところでByteStringに変換されて不可解なバグに悩まされる環境でコードは書きたくありません。

 結論としては、Scalaは関数型パラダイムの9割、C++11でも8割はサポートしているので残りの1〜2割のためにHaskellを導入して、余計なオーバーヘッドで四苦八苦するのは割に合わないかなと言うところです。

 それと、オブジェクト指向がオワコンかというと、そういうところはあるかと思いますが、既存のライブラリの多くがオブジェクトパラダイムで作成されているので、それらとの橋渡しが困難というのもあります。
 ようは、一つ未解決の問題として、オブジェクトを言語境界をまたいで渡す簡単な手法がないというのがあります。
 これはオブジェクトモデルが言語によって異なり、互換性が基本的にはないからです。
 SWIGなんかがあるにはあるわけですが、結局、クロージャーはおろかコールバック関数ですら言語をまたいで渡すのが非常に困難です。
 そのために多くのシステムでは、PODをバイナリなりJSONで渡すしかなくて、後はCスタイルのインターフェイスを通じて関数を呼ぶしかないわけです。
 これがあるためにRubyでプロトタイプを書いて、速度の必要な部分だけC++で書き直すというのが絵空事になってしまうと言う現実があります。例えば、railsのようなmagicalなフレームワークがどんなにウケたからといってボトルネックC++に書き直すことは結局為されていません。mongrel2が完全にCで書き直されrubyと独立してしまったのが興味深いです。
 特に、ここでCで書き直すというのがポイントで、C++では書き直せないのが溜まらなく苦痛です。
 これはRubyに限らず、Haskellも、Javaもそうで、インターフェイスはCしかないのは色々不便です。となるとQtのようなC++のオブジェクトシステムががっちり食い込んだフレームワークを他言語から使うのはだいぶ分が悪くなります。

 この問題を解決するにオブジェクトモデルを共有するほかなく、F#とScalaVMにそのまま乗っかかる形でうまくやっています。

 個人的には、D言語っぽいシンタックスの、C++を吐くだけの新規の言語に期待したいところです。