虎の穴開発室ブログ

虎の穴ラボ株式会社所属のエンジニアが書く技術ブログです

MENU

「関数型デザイン」を読んで、設計と実装の幅を広げよう!

当ブログを見ている皆さん、こんにちは。虎の穴ラボのy.fです。

本記事は虎の穴ラボ2024年夏の連載企画、23日目の記事です。

昨日はS.Sさんの「「システム設計の面接試験」で最適なシステム設計を学ぶ」が公開されました。ぜひご覧ください!

次は山田さんの「エンジニア組織を強くする 開発生産性の教科書」が公開されますので、こちらもご期待ください!

今週のテーマは「書評」ということで、最近出版された「関数型デザイン」という本を読んでみたので書評を書いていこうと思います!

store.kadokawa.co.jp

本書を読んだ理由

まず本書は、関数型プログラミングの本であるとともに、Clojureに強くフォーカスされている本でもあります。

clojure.org

もともとClojureは趣味で触っていたりしたので、その点で興味を惹かれたのが大きな理由です。

また、個人的には関数型プログラミングとオブジェクト指向は対立しているものという認識は持っていませんが、両者の比較について体系立てた説明を一度読んでみたいと思い本書を手に取りました。

目次

目次

第I部 関数型の基礎
 第1章 不変性
 第2章 永続的データ
 第3章 再帰と反復
 第4章 遅延
 第5章 ステートフル
第II部 比較分析
 第6章 素因数分解
 第7章 ボウリングゲーム
 第8章 ゴシップ好きなバスの運転手
 第9章 オブジェクト指向プログラミング
 第10章 型
第III部 関数型デザイン
 第11章 データフロー
 第12章 SOLID
第IV部 関数型の実践
 第13章 テスト
 第14章 GUI
 第15章 並行性
第V部 デザインパターン
 第16章 デザインパターンの評価
第VI部 ケーススタディ
 第17章 Wa-Tor

全体の感想

本書の表紙に記載されている、 関数型とオブジェクト指向の対立を解消する! に偽りなし!な一冊でした。

本書の大部分では、ある例題を元にオブジェクト指向版と関数型版のコードが示されます。コードを元に両方の利点や、何に着目してプログラミングされているかについて対比される構成になっています。

最終的にはオブジェクト指向の文脈でよく知られているデザインパターンについて、関数型で実践され、さらにそれらを応用して一つのアプリケーションを関数型とオブジェクト指向を融合して作っていくといった形になります。

本書を読むことで、オブジェクト指向と関数型どちらの考え方にも触れることができるので、自分のプログラミングや設計の考え方についての幅を増やしたい人にもおすすめできる本です。

ただ、注意しないと行けないのが、JavaとClojureどちらもある程度コードが読めるレベルにないと少し厳しいかなといった印象がある点です。 本書の構成上、オブジェクト指向プログラミングの代表としてJava、関数型プログラミングの代表としてClojureが取り上げられ、両者のコードを比較することで話が進んでいくためです。

Clojureについては簡単な説明が入りますが、Javaに関してはほぼ説明無しです。Clojureの説明もあるとはいえ薄いので、Clojure及びJava系の構文を持つ言語をある程度理解しておく必要はあるかと思います。 また、単に関数型というより、Clojure独自の機能もかなり出てくるので注意が必要です。

全体的にコードの分量も多く、Clojureのコードが沢山出てきます。なので、本書をきっかけにJavaやClojureについて学んで行くのもありかと思います。個人的にはClojureも好きなので流行るといいなと思っています。

第I部 関数型の基礎

この部では関数型を関数型足らしめている要素についての説明がされています。

初っ端で書かれていますが、著者の考えでは関数型プログラミングとは「代入文のないプログラミング」と定義されています。

各章では、そのような定義下で、一般的にプログラミング上必要とされているようなループ処理や、状態(変数)をどう扱えばいいかについて、Clojureで説明されています。

過去に関数型言語や、関数型プログラミングに触れたことがある人にとっては知っている内容が多いと思いました。 逆に全く触れたことがない方にとっては再帰なども出てきて刺激になる部かなと思います。

(再帰でカウントダウンするリストを作る関数)

(defn count-down [result n]
  (if (= n 0)
    result
    (recur (conj result n) (dec n))))

上記コードの引用元はこちら kimh.github.io

第II部 比較分析

この部では、各章のタイトルにもなっている例題に対して、Javaでのオブジェクト指向スタイルと、Clojureでの関数型スタイルのコードを比較しての分析について書かれています。

比較とありますが、決してどっちがいいとか悪いとか述べられているわけではありません。オブジェクト指向と関数型で何に着目してプログラミングされているのか、その結果処理がどのように書かれるかについて書いてあります。

この段階で現実的な課題に対するコードの例が示されるので、このあとの部について理解しやすい構成になっているのかなと思いました。

第III部 関数型デザイン

主にデータフローとSOLID原則について触れられています。

データフローについては、関数型プログラミングの文脈でよく出てくる話だと思います。 基本的には第I部であったように、「代入文のないプログラミング」がベースになるため、データを関数の引数に渡していく形になり、結果的にデータフローを意識する必要があります。 そのようなデータフローをClojureでコード上どうやって表現するかについて触れられています。

SOLID原則については、オブジェクト指向の設計といった文脈でよく触れられる原則かと思います。 この部では、オブジェクト指向だけでなく、関数型でもこの原則は有用であり、どのように表現するかについて書かれていました。

全体として、この部は基本的にはより設計に近い話が書かれているなと思いました。 そもそも何に着目するのか、よりよい表現をするためにどう考えるかが、データフローやSOLID原則をベースに書かれているなと感じました。

(スレッディングマクロでデータを流れるように処理しているサンプル)

(->> (count-down [] 10)
     (map inc)
     (filter even?)
     (reduce +))

第IV部 関数型の実践

より汎用的で抽象的な課題に対して関数型でどうやるかについて書かれています。

各章のタイトルにあるように、テスト、GUI、並行性について触れられています。

テストでは通常のテストコードの記述方法だけではなく、プロパティベーステストなどについても触れられています。 ちゃんとしたプロパティベーステストのコード見たことなかったので、かなり参考になりました。

GUIについては、ClojureのGUIライブラリであるQuilを用いた方法が紹介されています。特に、今まで書かれてきたように、データフローをベースにしてGUIを作る方法について触れられています。 昔Quilを少し触ったことがあったので、書かれている内容については理解できました。

最後の並行性については、よくある関数型だと安全、みたいな話ではなく、関数型でもレースコンディションなどは起こる可能性があるということが示されています。 利点の説明というより、関数型でも起こりうる事の説明といった感じで新鮮でした。

第V部 デザインパターン

タイトル通りです。デザインパターンのいくつかについて、関数型スタイルでも有用であり、それがどのように実装されうるのかについて書かれています。

デザインパターンがオブジェクト指向のためであり、関数型では不要であるといった誤解を解くための部のようでした。 関数型でもいくつかのデザインパターンは有用であり適用できるといったことがコードとともに示されています。

この部もかなりのコード量です。全部通読しても良いかとは思いますが、このパターンって関数型ではどうするんだっけ?と思ったときのリファレンスとして使うのも良さそうだなーと思いました。

第VI部 ケーススタディ

今までの総まとめで、一つのアプリケーションを作り上げる部になっています。

最終的には、「関数型」でオブジェクト指向のプログラムができるようになっています。

まさに、この本の謳い文句である、「関数型とオブジェクト指向の対立を解消する!」の部になっているなと思いました。

まとめ

本書は、「Clean Code」や「Clean Architecture」を書いたRobert C.Martin氏によって書かれています。通底する概念として、良いコードや良い設計とはなにか?と言ったものが本書にもあるなと思いました。

Clojure自体も今まで触れていない方にとってはかなり刺激になる言語ではあると思うので、単に関数型について知りたい人だけではなく、Clojureに興味がある人もぜひ手に取ってもらえるといいんじゃないかと思いました。

採用情報

虎の穴ラボでは一緒に働く仲間を募集中です!
この記事を読んで、興味を持っていただけた方はぜひ弊社の採用情報をご覧ください。
toranoana-lab.co.jp