世界を動かす技術を、日本語で。

数百万行のHaskell:マーキュリーにおけるプロダクションエンジニアリング

概要

  • Mercury社で 200万行規模のHaskellコード を運用する実例紹介
  • Haskellの型システム を活用した信頼性・知識伝達の工夫
  • 純粋性(purity) を「境界」として捉える現場視点
  • 新人エンジニア でも運用可能な仕組み作り
  • 運用現場での教訓 とベストプラクティスの共有

Mercuryにおける大規模Haskell運用の現実

  • Mercuryは フィンテック企業、30万以上の事業者にバンキングサービスを提供
  • 年間約 2億4800億ドル の取引処理、従業員約1,500名体制
  • 全エンジニアの多くがHaskell未経験 で入社、現場で習得
  • 約200万行のHaskellコードベース を運用、コメント等を除外した実数
  • 急成長・高頻度な人材入れ替え環境下での 知識伝達・システム保守性 の重要性

Haskellが大規模運用で機能する理由

  • APIに運用知識を組み込む ことで、危険な操作を安全な境界内に封じ込め
  • 型システム を通じて「安全な道」を「簡単な道」にする設計
  • システムの 理解容易性 を重視し、新人でもコードの意図を把握可能に
  • SVB危機 などの非常時にも、堅牢なシステム運用を実現
  • ドキュメントより型定義 で知識を残すことで、異動・退職時の知識喪失を防止

信頼性への考え方

  • 従来の「失敗を防ぐ」思考から、「 適応力を持たせる」へ転換
  • システムが 変動を吸収し、段階的に劣化する 設計を重視
  • 新人や短期間の在籍者が多い環境では、 組織的知識の伝達 が課題
  • 型システムを運用支援ツール と捉え、正しさ証明以上の価値を見出す
  • 安定性エンジニアリングチーム による事前の運用検討・リスク対策

純粋性(purity)は「境界」の設計指針

  • Haskellの 純粋性は「性質」ではなく「インターフェースが守る境界」 という現場観点
  • 内部で危険な操作(ミューテーション等)があっても、 型で外部から遮断 できれば許容
  • 例: runST の型(rank-2型)による安全なスコープ管理
  • 危険な操作は閉じ込め、外部からの誤用を防ぐ ことが本質
  • 新人にとって「 純粋性は維持すべき境界」という説明が実践的

「正しいこと」を楽にする仕組み

  • 大規模コードでは 操作順序や手順の遵守 が重要な場合が多い
    • 例: トランザクションごとに監査ログをflushする、通知をDBトランザクション内でenqueueする等
  • これらの「 作法」はドキュメントや口伝、Slackスレッド等に埋もれやすい
  • Haskellの型で 運用上の作法や制約を強制 できる
    • 例: 必須ステップを型で表現し、忘れや誤用を防止
  • 組織の知識半減期が短い中、 型による知識の永続化 が有効

まとめ

  • Mercuryでは Haskellを大規模・高頻度変化の現場 で運用し、成功体験を積み重ね
  • 型システム・純粋性の境界設計・知識伝達 が、システムの信頼性と運用容易性に直結
  • 現場で役立つHaskellの実践知 を、今後も発信予定

Hackerたちの意見

一般的な考えとは逆かもしれないけど、マーキュリーがハスケルを選んだことや、初期のリーダーたちの豊富な経験が、彼らの成功にかなりの影響を与えたと思う。マーキュリーの顧客として、彼らは本当に私のツールキットに欠かせない会社で、ハスケルを選んだことで、彼らの進展や開発、全体の旅がより良くなったと感じざるを得ない。もちろん、ほとんどの言語で同じことが言えるけど、FP言語のハスケルが成功のレシピだとは言わない。でも、「バイブコーディング」やLLMの時代の前にこの意図的な選択をしたのは特に先見の明があったと思うし、投稿で詳しく説明されている彼らのエンジニアリング文化とも相まっている。

一般的な経験がない人を雇うことが実際に役立ったと思うよ。新しいメンバーに自分たちの文化やスタイルをゼロから植え付けられたからね。事前に雰囲気を作る前は、ほとんどの人が何の指示もなくいきなり作業に飛び込むことなんてしたくなかっただろうし。

彼らのアプリは本当にすべてがうまくいくって感じがする。ほかのサービスから来た身としては、すごく満足感があるよ!

キャリアの初期にハスケルの仕事を見つけて、それに専念するのが大事だと思う。入り込むのが本当に難しいから、経験がないと、ハスケルの経験がある他の人たちと競争しなきゃいけないし。仕事は珍しいから、もしうまくいかなくなったら(会社が働きにくくなったり、レイオフされたり)、身動きが取れなくなるかも(まあ、RustやScala、F#に切り替えるかもしれないけど)。

多くのハスケル開発者を採用してきた者として言えるのは、ハスケルの経験が多いことが必ずしもプラスとは限らないってこと。実際にものを作りたいと思っている開発者を確保するために、慎重にフィルタリングしなきゃいけない。ハスケルに後から来たけど、実際にものを作る経験が豊富な人を採用したい。ハスケルの経験が豊富でも、あまり成果を出していない人は大きなリスクだと思う。

特にHaskellのような言語や、Haskellを本当に愛している人を雇うことに対しての不安があるんだ。ツールを問題よりも重視するような特定の性格の人が集まるリスクがあるから。自分もそういう人だったし、そういう人と一緒に働いたこともあるし、そういう人の犠牲になったこともある。彼らは言語XやフレームワークYが大好きで、目の前の問題がそれを使うことで解決できると信じている。今や彼らはハンマーを持っていて、それで釘を探し回っている。Haskellを使っている職場にいたこともあるけど、まあ…普通だったかな? 書くのが好きな人にはいいかもしれないけど、個人的には他のFP言語の方が好きだな。そういうオタクなことが好きで、Lambda the Ultimateとかによく出入りしてたけど、Haskellや他のツールに特別な力があるとは思わない。そういうアプローチで何度も痛い目にあったから。

これ、私にもあった。Haskellで10年間で全ての収入を得た。数百万。全てのものをそれで買った。最初はLinkedInのリクルーターから始まったんだ。

200万行のハスケルが何をしているのか、想像するのが難しい。すごい量のコードだし、ハスケルは「タイト」っていう印象があるから、少ないコードでたくさんのことができるんじゃないかな。もしかしたら、jsonのシリアライズやデシリアライズ、REST APIフレームワーク、ログ記録などをするためのライブラリがたくさんあるのかも?

TFAから: > 問題は、我々が計測できないコードを信頼できないことだ。もしサードパーティのバインディングが具体的な関数を通じてHTTP呼び出しを行うなら、トレーシングを追加する方法も、SLOに合わせたタイムアウトを注入する方法も、テストでパートナーの障害をシミュレートする方法も、トレースの400msのギャップを説明する方法もない。だから、自分たちで書く。最初は手間がかかるけど、我々が書くクライアントは構造上観測可能だから、最初からそのように作った。

ニット: あなたが「タイト」と呼ぶ言語の質は、通常「表現力豊か」と呼ばれる。少ない文字で比較的抽象的なアイデアを表現できる。これを「高レベル」と呼ぶ人もいる。ただ、200万行のコードは、一見思えるほど多くはないと思う。特に金融のような高度に規制された分野の会社にとっては、数年の進展を考えると。

コードベースがどうなってるかは分からないけど、a) Haskellの簡潔さの評判は、学術的なサークルでの過剰な代表性から来てる部分があるんだよね。そこで「St M -> C T」みたいなことを言うのは普通なんだけど、実際のソフトウェアでは「TransactionState Debit -> Verified Transaction」みたいに言う方がずっと役立つよね。b) Haskellの簡潔さの評判のもう一つの要因は文化的なもので、LISPにさかのぼるものがある:人々が難解なトリックやマクロを使って行数を節約しようとしすぎること。たぶん、Mercuryみたいな金融系の会社では、明瞭さや可読性を重視して、そういうのは避けられてると思う。例えば、リントがモナディックなものを堅苦しいマルチラインのdo式に分けるように強制するかもしれないし、>>や>>=で一行で書けるのに。

Haskellは「タイト」 これは客観的な指標じゃないけど、Haskellは単に違う「アスペクト比」を持ってると思う。行数は少し低いかもしれないけど、単語数はより命令的なOOP言語とほぼ同じだよ。

Hacker Newsで議論の続きを見る