はじめに
シリーズ記事が10本目まで出来たので、ポエムを1本書きます。
テーマは「Haskellで作ってみるアプリの題材は?」です。
実用アプリの狙い目としての「WebAPI」
関数型言語に興味ができたとして「Haskellにトライしてみようかな?」と思ったとしましょう。他の方も書かれていますが、実際にコードを書いてみないとHaskellのすごさは実感できないと思います。せっかく時間や労力をかけてコードを書くであれば、実用アプリを作った方がいいのでは?と個人的には思います。
実用アプリを作るとはいっても、やりたいことによってはHaskellでできるかどうかはわかりづらいでしょう。その点でいくと、WebAPIというのは非常にお手頃なテーマかと思います。
- 必要な入出力がはっきりしている(RDB、Webインターフェース)
- WebAPIフレームワークが用意されている(Servant, Persistent/Esqueleto)
- 必要な実装内容は(そこまで複雑ではない)データ処理だけ
- APIハンドラ実装は、純粋関数というようりアクションがメインになるので、関数型言語特有のハードルが(ちょっとだけ)低い
実は、WebAPIを実装し始めたころは、「WebAPIなんてRDBの中身をちょこっと加工して出したりするだけなのに、Haskellでやるというのも大げさか?」と思ったりしたのですが、機能が増えていくに従ってコードはどんどん大きくなっていったのでした。
Haskellで実装して(気持ち的に)得たもの
趣味や業務で様々なプログラミング言語で数々のプログラムを30年以上作ってきましたが、Haskellをやってみて初めて実感したことがあります。
- 機能を実装した時に、一発動作する確率が異常に高い
- 「一から作り直したい」という気持ちが出ない
一つ目の話は、既に多くのHaskellerが語っている「ビルドが通った時点で、既に多くのテストを通った状態」というやつですね。これまでは「簡単なプログラムであっても、実装しただけで一発動作することなんて千か万にひとつかな」と思っていました。ところがHaskellだと、RDBを操作するアプリであるにも関わらず「ビルドが通ると『まず動く』」ですからね。この違いはでかいです。もちろん、最初のうちは「ビルドを通す」というところに行くまでのハードルが高かったのですが。
二つ目の話も、これも既に語られている話ですが、Haskellは「リファクタリングのハードルが非常に低い」です。これまでの経験だと「ここのテーブル定義はこうしたい」とか「データ構造や関数インターフェースはこうした方が」と思うことがあっても、その修正にトライするための(心理的な、あるいは工数的な)ハードルが高く、リファクタリングをしないことも多いです。最初のうちはそれでよくても、無理をしていくと歪みも大きくなっていくので、「どうせなら一から作り直したい」と思うシーンは必ず出ます。HaskellでWebAPIを実装するにあたって、リファクタリングをしても、それによるバグの発生はほとんどなかったため、相当の数のリファクタリングを行いました。リファクタリングの時に発生する修正作業は、コンパイラ(のエラーメッセージ)が全て教えてくれるので、頭を使う時間が短く、結果としてエディタを操作している時間が長くなり、左の小指をちょっと痛めてしまったくらい、でした(Emacs使いなもので)。
Haskellで実装して(運用的に)得たもの
ここの話は、本題の記事で書く予定ですが、Haskell(Servant+Persistent/Esqueleto)で実装したおかげで、下記の管理が不要になりました。
- RDBのテーブル定義
- APIハンドラではない定期タスク
なお、UI側がElmであれば「APIインタフェースの型情報の共有」というメリットも得られたでしょう。
もちろん課題もありますが
今回、実装したWebAPIについての技術課題は、概ね解決していますが、他の方の実装では別の課題が出ることもあるでしょう。正直、PHP等と比べると情報は非常に少ないでしょうが、そのデメリットを考えても差し引きプラスにもっていけるポテンシャルはあるのではないかと思っています。足りないノウハウは、積み重ねをしていけば、どうにか...ね。
まとめ
どの技術でもそうですが、話だけをいくら聞いても意味がないので、こういった能書きの話も単体ではあまり意味はないのですが、Haskellにトライするひとつのきっかけになれば、と思います。
次のポエムは本題の方が20本目になったら書こうかな、という予定です。