こんにちは、株式会社AGE technologies CTOの黒川です。
この記事では、私たちがシステム開発のほとんど全ての場面で使用しているClojure(クロージャー)という言語について紹介します。大きく下記の3点をトピックとして、弊社のテクノロジースタックに理解を深めていただくことを目指します。
- なぜClojureを選定したのか / Clojureが「私たち」にもたらすもの
- Clojureが「あなた」にもたらすもの
- 未経験のチームメンバーがどうやって適応していったか
前提
私は、現代のシステム開発のユースケースにおいて、特定の言語でなければ実現できない機能はほとんど存在しないと考えています。とはいえ、「じゃあCOBOLでもいいよね」といった極論は必ずしもベターな解決方法ではなく、選定する技術に応じたトレードオフは理解しておく必要があります。
この前提に基づいて、本記事では私たちの技術スタックが、どんなトレードオフを踏まえた意思決定なのかをご紹介しようと思います。
なぜClojure(クロージャー)?
私たちがClojureを利用している理由は、私たちが解くべき課題に対して素直な解決方法をもたらしてくれる言語だからです。
解くべき課題の特徴
私たちが最初にチャレンジしている領域は「相続手続きの効率化」です。このドメインに求められるのはCtoCのコミュニケーション活性化やエンタメアプリのリッチな表現ではなく、確実な手続き進行を可能にする業務システムです。
データモデルは歴史的背景によって、とてもバリエーション豊かです。たとえば不動産の情報ひとつ取っても、既存の制度によって形式が規定されているものの、制度改革やデジタル移行を経て長年メンテナンスされてきたため、想定外の形式になっていることが多々あります。IDがnullだったり、SQLアンチパターンで言う「ジェイウォーク」パターンを踏んでしまっていたり...。
これらの特徴から、私たちのソリューションは、所与のデータモデルを柔軟にサポートできる必要がありました。
Clojureの特徴
Clojureは、Java上で(またはAltJSとして)動作する動的型付けの関数型言語です。この言語の出自や詳細な解説は公式ドキュメント(コミュニティによる日本語訳)や専門的な記事に譲りますが、大まかに下記の特徴を持っています。
- シーケンス(リストやマップ)を処理するのが得意
- 文法が少なく、かつマクロ(コードを生成するコード)で簡単に拡張できる
- デフォルトで状態を持たない(イミュータブル)ことを強く要求してくる
これらの特徴は、私たちが現在チャレンジしている事業領域において、強い武器になると考えています。まず、業務システムは一般に大量のシーケンスを整形・保存・読み出しする必要がありますが、これらはまさにClojureが最も得意とする作業の一つです。
イミュータブルさを強要される点も、パフォーマンスやテスト可能性、メンテナンス容易性に寄与してくれます。たとえばClean Architectureの文脈では、外部システムとの接続や状態管理をコアロジックから切り離すことを提言しています。またReactをはじめとする仮想DOMライブラリは、リリース当初から状態管理の難しさと戦い続け、現在は関数コンポーネントを利用することを推奨しています。
Clojureの文化
Clojureユーザーのコミュニティは、
- 小さなライブラリを作る
- ライブラリを組み合わせる小さなコードでユースケースを満たす
- すべてをデータとみなし、シーケンスの世界に持ち込む
というエコシステムを維持しています。
たとえばClojureにおいて比較的よくつかわれるDIコンテナのコードベースは500行で完結します(weavejester/integrant)。これ以外でも同じように、小さく単一の役目を確実に果たすライブラリがたくさんあります。
また、データ指向な思想はフロントエンドにおいても発揮されています。HTMLや仮想DOMをシーケンスとみなすライブラリがあるおかげで、たとえば普通にJSXを書くと
const label = text => {
return <div class="label">
{text}
</div>;
}
と書くべきところを
(defc label [text]
[:div {:class "label"} text])
のように、リストとして記述することができます。
(Wantedlyさん、シンタックスハイライトの導入お待ちしてます)
XMLはもともと木構造の記述スタイルのひとつであり、木構造はネストするシーケンスで記述可能ですから、この開発体験はデータ指向な言語の強みが発揮されている場面だといえるでしょう。
私たちのトレードオフ
最初に申し上げたとおり、すべての設計上の意思決定にはトレードオフがあります。私たちはClojureによって、関数型でデータ指向なシステム設計や、シーケンス処理の便利さを手に入れました。では、逆に何を手放したのでしょうか?
私たちが明確に手放したものは、開発者が豊富にいる環境です。
関数型な開発体験やClojure自体の経験を持つ方は、それ以外の環境の経験者に比べれば多くはありません。Qiitaを読んだりChatGPTに質問すればある程度の回答を得られる環境でないと言えるでしょう。
Clojureでも回答はしてくれますが、若干の間違いを含んでしまうのに対し、laravelのスキーマは完璧です。開発者の量という相対的な意味でLLMを使った開発体験を享受しづらい点は、私たちが手放したトレードオフを分かりやすく表してくれます。
とはいえ、私たちの技術スタックに興味を持ってくださる方は学習体力が高いことがとても多く、皆さんにこのピーキーで自由な環境を楽しんでもらっています。
Clojureが「あなた」にもたらすパワー
Clojureの特徴は十分にご理解いただけたかと思いますので、次は私が採用面談などで話している、皆さんがClojureによって得られるものを紹介させていただきます。
まず、特にフリーランスの方にとって、Clojureは残念ながら次のClojureの仕事を持ってこない事が多いです。Clojureは世界規模で見ると最も高給取りな言語ですが、日本のマジョリティではないことは、ご認識いただいている通りかと思います。
しかしClojureは、エンジニアの皆さんにとって、プログラミングおよびWebサービス開発においていくつかの本質的な学びをもたらしてくれます。
関数型プログラミングへの適応
関数型プログラミングは言語を問わず実現可能な思想です。しかし、ミュータブルな言語に後から取り込まれた関数型な機能よりも、元から関数型な思想で作られた言語に触れる方が、学習効率は高いでしょう。
Clojureは実用的な範囲で関数型な書き方を強制してくれます。よって、この言語を書き慣れる頃には、どんな環境でもイミュータブルな静けさを実現できるようになっているでしょう。
一次情報にアクセスする勇気
上述したとおり、Clojureは小さなライブラリ群を集合させて機能を実現させるエコシステムを形成しています。ですのでコードジャンプした先の外部ライブラリでも、簡単に読み通すことができます。
DeepLやChatGPTなどのサポートツールによって、新しいことを学ぶハードルは日々下がっていますが、世界で読まれているドキュメントや愛用されているライブラリのコードベースに触れる機会は、自分の底力を上げるチャンスになります。
またClojureを利用した開発チームでは、ライブラリが薄いからこそ、適度にWeb標準やブラウザ標準を理解しておく必要性に迫られます。これらの特徴から、Clojureに触れることは、エンジニアの方にとって一次情報を活用して学ぶ習慣をつける助けとなるでしょう。
アーキテクチャから疑う姿勢
これまでの話から推察できるとおり、Clojureを用いたシステム設計はデファクトを提供しません。
著名なライブラリやフレームワークはある程度安定していますが、それをどう自分たちの課題に適応していくかは自分たちで考える必要があります。1年前に相対的に正しかった意思決定が、今も正しいとは限りませんが、Clojureはその環境の変化に追随できる柔軟性を与えてくれます。
もちろん、意思決定を取り込める柔軟性を実現するには、様々な言語のフレームワークや著書から学ぶ必要があります。しかし、それこそ開発チームが自分たちの課題を解決するために頭を捻るべき点でしょう。
Clojureを使う経験はあなたに、
- フレームワークの挙動は変更可能だ
- アプリケーション全体を俯瞰して、ベターな意思決定をシステムに反映すべきだ
という思想を与えてくれます。これは今後、どんな環境で働くにせよ役に立つ問題解決の姿勢です。
私たちの開発チームについて
さて、様々な話をしてきましたが、最後にここまで興味を持って読んでくださった方に向けて、いま私たちの開発チームで活躍してくれているメンバーについて紹介しようと思います。
どんなバックグラウンドからジョインしたのか
私たちはこれまでに20名ほどのエンジニアを受け入れてきましたが、そのほとんどはClojureを書いたことのないメンバーでした。バックグラウンドには、市場環境どおりにPHPやJava、TypeScriptの経験を持つ方が多いです。
どれくらいの期間で立ち上がっているか
特殊な文法に慣れるのには時間がかかるかと思いきや、ほとんどの方は2~4時間のペアプロで簡単なチケットを独力で遂行できるようになります。むしろ、Webシステムの設計原則やReactのコンポーネントライフサイクルに触れた経験が少ない場合、そちらの方がクリティカルにパフォーマンスに影響を与えてきました。
文法によるハードルは想像以上に低く、本質的な力が問われることが分かります。
Clojureを使う前後のマインドチェンジ
Javaの業務システム開発から弊社でのフルコミットに転換したチームメンバーに聞いたところ、
- 参照透過性のおかげでコードリーディングの時間が圧縮され、意図しない挙動の原因分析やリファクタリングがしやすくなった
- オブジェクト指向を含む他の言語でも、イミュータブルさを意識してコードを書けるようになった
- 多くのサードパーティライブラリーが数十行で終わることが多いため、使い方も内部実装も分かりやすい
とのことです。上述したような特徴を存分に体験していることが分かります。
最後に
以上、私たちが技術スタックの中心に据えているClojureという言語と、それを私たちがどう評価しているかについて話させていただきました。
少しでも興味の沸いた方は、ぜひ気軽に話しに来てください。より具体的な開発体制や設計指針についての議論をしましょう。ご応募お待ちしています。