# ポリグロットの正しいやり方

> Source: https://www.ymotongpoo.com/works/adopting-erlang-ja/team_building/how_to_polyglot/


Erlangを導入するということは、既存のコードベースを持たない新しい会社でもない限り、組織がポリグロット(複数言語併用)になる計画を立てるということです。ロードマップ上で既存コードをすべて置き換える計画であったとしても、その間はポリグロットである移行期間が必ず存在します。したがって、ポリグロットなワークフローを適切に支える計画を立てるべきです。

この章では、ポリグロットにまつわるよくある誤解や思い込みを扱い、言語として存続可能であるための基準を設けることを提案し、組織が直面しやすいいくつかの難しい論点を取り上げます。

## ポリグロットにまつわる誤解

エンジニアたちが組織をポリグロットにするという案について議論を始めると、さまざまな主張や思い込みが持ち出されます。よくある不満を見ていきましょう。

- サポートすべきツールやビルドチェーンが増えるほど、ビルドまわりの工学が複雑になる
- 依存関係が増えるほど、すべてを最新に保つための監査や保守が必要になる
- 時間が経つにつれ、一部の言語は人気を失い、育成にも採用にも書き直しにも余計な労力がかかるようになる
- すでにポリグロットな状態にあり、他の誰も知らない言語でかつて誰かが書いたせいで誰も触りたがらないコンポーネントがある

ビルドまわりの工学は正当な懸念です。専任のIT部門を持つ多くの組織が、サポートすべき構成の数を減らすために、全開発者に単一機種のコンピュータを配布するのと同じ理屈です。とはいえ、コンテナ化が広く普及した今、この問題の深刻さは薄れています。DockerのイメージやKubernetesのようなランタイムは、ローカルの開発環境から本番稼働までを一貫して扱えるインターフェースをすでに提供しています。各プログラミング言語に詳しい人たちの協力でビルドイメージを保守していけば、時間とともに関係する複雑さの大半は軽減されます。

依存関係の急増や監視を回避するうまい方法は、問題を検出して報告してくれるツールを使う以外にはあまりありません。依存関係の表面積は基本的に複雑さの管理の問題であり、必ずしも使っている言語の数と結びついているわけではありません。たとえば、会社全体の一部門で使われている確立されたErlangのソフトウェアより大きな依存関係ツリーを持つJavaScriptのデモプロジェクトを、私たちは見たことがあります。依存関係の脆弱性スキャナのような他のツールがHexパッケージをサポートするようになってきているのも事実です。

各依存関係をセキュリティチーム、法務部門(ライセンスの観点から)、エンジニア(コード品質の観点から)が審査しなければならない手続きを会社が持っている場合、実際にはあまりうまく機能しないことが分かるはずです。人々は事前承認済みのライブラリ一覧に頼りきるか、トップレベルの依存関係しかレビューしないかのどちらかになりがちです。手続きの煩雑さを避けたいがために、古くなったライブラリを二度と更新しないケースもあります。逆に、開発者が素早く出荷したいと感じたときに、複数部門をまたぐレビューを避けるためにその場で依存関係をプロジェクトに書き足してしまい、ほとんどレビューを受けない、しかも既存のライブラリを書き直したせいで品質の低いコードができあがることもあります。私たちはこれを、プログラミング言語の問題ではなく組織の問題だと考えています。

人気のない言語や「採用しにくい」言語は、常に問題であり続けます。残念ながら、これは実際には解決できない問題です。誰も未来を知らないからです。人々が好まなくなった単一の主力言語だけを持ち、スタック全体の人材確保が難しくなるのと、スタックの半分だけが採用しにくいのとでは、どちらがより悪いでしょうか。2.xから3.xへの移行があまりに困難で、ライブラリやコンポーネントが実質的に別言語とみなしているPythonのような事例はどうでしょうか。私たちは、単一の言語に縛られず、いくつかの言語(ただし大量にではなく)を切り替える習慣を持つ組織のほうが、プログラミング言語市場の変化にうまく適応する訓練ができていると考えています。

次に、組織が何をしていて何を知っているかを気にせず、他の誰も知らない言語で成果物を出荷し始める一人だけの開発者への不満があります。その開発者は履歴書に書ける実績作りとしてそうしているのかもしれず、その後、転職してみんなを置き去りにするかもしれません。単一の言語を義務付けたところで、これに対する防御策はありません。それどころか、開発者は会社の主力言語を使いながら、その言語やライブラリの一つがサポートする新しいフレームワークや新しいパラダイムを試すことで、同じことをしでかす可能性もあります。既知のデプロイの文脈における新しい言語よりも、サポートされていない単一の[Lambda](https://aws.amazon.com/lambda/)のほうが厄介な場合すらあります。

私たちはこれをおおむね、対処すべきプロセスの失敗だと考えています。そのような作業が完全に孤立した状態で行われることが問題であり、使われたツールを責めるべきではありません。

最後に、反論すべき大きな主張が一つあります。言語が多いと壁が生まれ、単一の言語と単一のフレームワークを使ったほうが開発者の異動がしやすくなるというのは、一般に受け入れられている考えです。実のところ私たちは、これこそがポリグロット組織に対する最大の誤解だと考えています。

これが的外れである理由は、開発者を機械部品のように扱っているからです。インターフェースさえ同じであれば交換可能だという考え方は、言語に関係しないあらゆる要素を無視しています。チームが違えば慣れる必要のある習慣や力学も違います。異なる歴史と課題を持つプロジェクトに取り組んでおり、領域も、重視する点も、設計上の妥協点も異なっているかもしれません。さらに言えば、同じ言語の中でさえ移行にはコストがかかります。異なるフレームワーク、ライブラリ、ツールチェーン、あるいはそれらのバージョン違いにも、それぞれ何らかの適応が必要になります。

これらの要因を合わせると、新しいプログラミング言語を学ぶのと同じか、それ以上に大きな課題になることが多いと私たちは主張します。たとえその課題が大きいとしても、新しい言語を学ぶコストは見た目ほど高くありません。なぜなら、そのコストにはこうした根底にある課題がすべて含まれているものの、それらは単一の言語の中にもなお存在しうるからです。コストが高く見えるのは、こうした難しい事柄へのサポートを従来まったく提供してこず、エコシステムやチームを移るたびにゼロから学び直さなければならなかったからにすぎません。

## 実用最小限の言語

前に挙げた誤解やよくある不満を踏まえ、使われているプログラミング言語に関わらず、根底にある課題に直接対処するアプローチを提案します。あるプログラミング言語を採用してよいと判断するために満たすべき最低限の基準も提案します。これらを最初から厳格な規則として提示したくなるかもしれませんが、エンジニア自身にその策定に参加してもらうほうが、他のやり方より納得感と自律的な運用が得られると私たちは考えています。

**実用最小限の言語(Minimum Viable Language, MVL)**が何を意味するかを決めるうえで最初に押さえておくべき視点は、開発者どうしが互いに教え合いながら継続的に適応していく学習する組織へと組織を導きたいということです。目的は、学習の方向性を示し、あるチェックすべき技術がどの程度の成熟度に達していれば検討に値するかの境界を与えることにあります。

そのために、長期的にサポートし続けるコストを明らかにすることを提案します。開発者がそのサポートについて妥当な道筋を示せる限り、その言語を禁じる理由はありません。たとえば、次のような問いに答えてもらうとよいでしょう。

- どのようにデプロイするか
- どのようにオブザーバビリティを提供するか。メトリクス、ログ、トレーシングのサポートはどうなっており、プロジェクトにどう組み込むか
- どのビルドツールを推奨し、開発者はどのように開発環境をセットアップすべきか
- どのテストフレームワークが提供されており、全体のテスト基準とどう整合させるか
- どのようにドキュメントを書くか
- 将来この言語について誰に質問すればよいか。社内に専門家や推進者はいるか。何人いて、その人数がある基準を下回ったらどうするか
- RPCやメッセージパッシング、データのシリアライズを行う、あるいは特定のデータベースを使う場合、それぞれどのライブラリを使うべきか。自分たちで書く必要はあるか
- その言語でのコードの構造化・記述・デバッグにはどう取り組むか。提供すべき基本的なガイドラインやツールはあるか
- その言語の開発者をどう採用するか。その言語を知らない人をどう育成するか
- 上記のいずれかに手を付け始める人を助けるための基本的なオンボーディング資料はあるか

これらの問いは必要に応じて追加・削除してください。メモリのフットプリント、フロントエンド言語やモバイル開発、バックエンド言語、デスクトップソフトウェアなど、状況に応じて文脈を補ってもよいでしょう。エンジニアが提供されるべきだと考える基準をまとめてください。単一のプログラミング言語を想定せず、抽象的な形で答えてください。項目のいくつかを「必須」「あれば望ましい」などに分類してもよいでしょう。次のような表にまとめられるはずです。

| 項目 | 必須 | あれば望ましい | 理想の世界では |
|---|---|---|---|
| HTTPサーバ | 素のサーバ | Webフレームワーク | コミュニティに支えられた人気のWebフレームワーク |
| gRPCライブラリ | シリアライズ/デシリアライズ | フルスペックのgRPCクライアント/サーバ | ドキュメントの整った例 |
| マイクロサービス | サンプル実装 | テンプレートライブラリ | 完全なチュートリアル |
| 社内の専門家の人数 | 2人 | 4人 | 10人以上 |
| 採用のしやすさ | まとまった規模の地元コミュニティ | 大学で教えられている | みんなが知っている |
| オンボーディング | 各自が独学で身につける | 一部のドキュメントが存在する | チュートリアルとトレーニングが提供される |
| オブザーバビリティ | ロギングとメトリクスのライブラリ | 言語やフレームワーク固有のログ/メトリクスのガイドライン | OpenTelemetryのサポート |
| テスト | 単体テストフレームワーク | 結合テストフレームワーク | 高度なテストフレームワーク(プロパティベーステスト、ミューテーションテストなど) |
| ... | ... | ... | ... |

満たすべき基準、つまりそれがなければその言語を採用できない必須項目などを定めてください。これを、意思決定の検証に使えるかなり客観的なスコアカードに仕上げます。そうしなければ、CTOやアーキテクトが実際のサポート状況を顧みずに自分の好みの技術を推し進めることになりがちです。組織のデフォルトの反応は、上の立場の誰かが気に入っている何かを見つけてそれを推し進め、残りの組織にはその気まぐれに合わせてもらうというものです。スコアカード(単純にしても複雑にしてもかまいません)の狙いは、技術の採用や変更にかかるコストを人々に意識させることと、互いに使いこなす手助けをするために何を提供する必要があるかのチェックリストとして機能させることにあります。

採用したい言語に対してスコアカードを試し、実際にうまく採用できそうか、うまくやるために何が足りていないかを確認してください。すでに採用済みの言語に対しても試し、通過できるかどうかを見てください。通過しなければ、まずその差を埋めることから始めます。エンジニアが自分の仕事をより効果的にこなすために必要だと感じていることに沿って、知識ベースを育ててください。会社の一部の領域に合わせて要件を専門化・適応させ、それがどこに落ち着くかを見てください。

単一言語を義務付けている会社であっても、「あれば望ましい」やそれ以上の項目の多くが欠けている可能性は十分にあります。そのサポートをコミュニティ任せにしてしまうと、結局は社内のサポートも資金不足に陥ります。レガシーなコードベースはそうやって生まれます。また、チームによって自分たちの専門領域に関する物事の判断基準がまったく異なることに気づくかもしれません。インフラのコンポーネントを常に扱う人たちは、エンドユーザー向け機能に取り組むチームとはまったく異なる要件を持つことになるでしょう。スコアカードを専門化したり、領域固有の要素を組み込んだりすることから始められます。

## 本番投入できる言語

これまで定めてきた基準を繰り返し検討していく中でも、最終的な目標をいくつか念頭に置いておくべきです。たとえば、次のような事柄をカバーし終えた状態を目指すとよいでしょう(この文章自体がこれらの多くをカバーしているのは、より多くのErlangユーザーにとって物事を簡単にするためです)。

- 必要なバージョンをすべて揃えた開発環境の導入とセットアップの方法
- 検証済みでほとんどのプロジェクトが使っている推奨ライブラリの一覧
- 新しいプロジェクトを始める際の手順(テストのセットアップ、使用するリンター、CI/CDの立ち上げ方、コードスニペットやテンプレートなど)
- 助けを得られる場所(社内メーリングリストやチャットルーム、連絡すべき人の名前など)
- 書籍、チュートリアル、動画、あるいは役に立った社内文書などをまとめた学習リソースのライブラリ
- セキュリティに関するガイドライン
- サービスやアプリケーションを本番投入できる水準にするためのチェックリスト
- コードのベンチマークの取り方
- コードの計装のしかた
- アーキテクチャとコントリビューションのガイドライン
- よくある問題に対するランブックとプレイブック
- 面接での質問事項

これらすべてをWikiの大部な チュートリアルにする必要はありません。ペアプログラミングやランチ勉強会、プレゼンテーションなどで済ませられるものもあります。こうした項目についてどのようなオンボーディング支援を選ぶにせよ、採用した開発者やチーム間を異動する開発者は、明示的なサポートがないまま、こうした事柄すべてを結局は自力で解き明かすことになっている点に注意してください。この見えない作業は常に行われています。目指すべきは、それを見える形にすることです。

ポリグロットな言語をサポートし、あるプロジェクトから次のプロジェクトへ人が移る際に(技術を孤立させることなく)何が必要だとチームが考えているかを明らかにすることで、そうしたサポートを持たない単一のプログラミング言語だけの環境より、チーム間の異動をむしろ容易にできる可能性が高まります。こうした原則を本当に組織の文化の一部にしたいなら、標準的な実践に到達し改善することに参加するチームや、既存のコードベースを望ましい水準まで引き上げる作業をするチームを評価する姿勢を示してください。こうしたリソースを段階的に構築し、生かし続けるための十分な賛同を得るのは難しいこともあるため、この最後の点は特に重要です。

要するに、人々がすでにすべてを知っているふりをするのではなく、どう学んでいくかに目を向け、それを後押ししましょう。ドメイン知識についての入門ガイドを用意してください。現在エンジニアへのサポートが手薄で、投資が必要かもしれない領域を洗い出してください。言語固有の知識やツールを組織的に維持し続ける仕組みを確立してください。そして、重要だとは思っていなかったものの、実はチームの仕事にとって欠かせないと分かる要因を見つけ出してください。

