はじめに — 再び熱くなったフォーマッター論争
2026年前半、GeekNewsとHacker Newsでコードフォーマッターの話題が再び盛り上がりました。gofmtより厳格な「意見のある(opinionated)」ツールであるgofumptが注目され、Rustで書かれた超高速のPythonツールruffが事実上の標準に定着したことで、「ツールが我々の代わりにスタイルを決めてくれるのは良いことか」という古い論争が再燃しました。
この論争は実は新しくありません。タブかスペースか、中括弧を次の行に置くか、セミコロンを付けるか。こうした問いはソフトウェアの歴史と同じくらい古く、チームごとに激しい宗教戦争を生んできました。しかしこの10年で流れが変わりました。「フォーマットはツールが決め、人は論争しない」という哲学が勝利したのです。本記事はその勝利がなぜ起きたのか、そして各言語エコシステムのツールがどんな哲学的選択をしたのかを見ていきます。
核心的な主張はこうです。良いフォーマッターの価値は、それが作るスタイルが「正しい」からではなく、スタイルに関する論争そのものをなくすからです。意見のあるツールは選択肢を奪う代わりに認知的自由を返してくれます。
フォーマッターは何を解決するか
フォーマッターの価値を理解するには、それがない世界を想像すればよいのです。チームメンバー五人がそれぞれ違うインデント、違う改行ルール、違う括弧スタイルでコードを書きます。Pull Requestのdiffは実際の変更とスタイル変更が入り混じってレビューが難しく、コードレビュー時間のかなりの部分が「ここに空白を一つ足してください」といった無意味な指摘に浪費されます。
フォーマッターはこの問題を根本的に解決します。保存する瞬間、あるいはコミットする瞬間、すべてのコードが一つの定められた形式に変換されます。結果として得られるものは三つです。
- **論争の終結**: スタイルはもはや議論の対象ではありません。ツールが決めます。
- **一貫性**: リポジトリ全体が一人が書いたように見えます。コードベースを読む認知負荷が下がります。
- **きれいなdiff**: フォーマットが常に正規化されているのでdiffには意味のある変更だけが残ります。
三つ目が特に重要です。スタイル変更がdiffを汚染しなければ、レビュアーは実際のロジック変更だけに集中できます。
意見のある度合いのスペクトラム — 厳格さ対柔軟さ
すべてのフォーマッターが同じ哲学を持つわけではありません。ツールは「どれだけユーザーに選択権を与えるか」という軸で異なる位置に立ちます。
一方の端にはgofmtがあります。設定がほとんどありません。Goチームの決定は明確でした。「フォーマットに関する論争は時間の無駄だ。一つの正解を定めて全員が従え。」オプションがないこと自体が機能です。誰も`.gofmt`設定ファイルをめぐって争いません。
反対の端には従来のツールがあります。数百のオプションを提供してチームが望むとおりにスタイルを組み立てられるようにします。柔軟ですが代償があります。オプションが多いと、そのオプションをめぐって再び論争が起こります。
このスペクトラムを表にまとめると次のとおりです。
| ツール | 言語 | 哲学 | 設定可能性 |
| --- | --- | --- | --- |
| gofmt | Go | 最小オプション、一つの正解 | ほぼなし |
| gofumpt | Go | gofmtより厳格 | なし(より強い) |
| prettier | JS/TS など | 意見があるが一部オプション | 少数オプション |
| black | Python | 妥協なきフォーマット | 極少 |
| ruff | Python | 超高速、フォーマット+リント統合 | 幅広く調整可能 |
興味深いのはgofumptです。これはgofmtが「十分に厳格ではない」と見た人たちが作ったツールです。gofmtが許す微細な自由さえなくしてより一貫した結果を出します。「意見のある」方向にもう一歩踏み出したのです。
各ツールの哲学を覗く
gofmtとgofumpt — Goの無寛容
Goは最初からフォーマットを言語文化の一部にしました。`go fmt`コマンドが標準ツールチェーンに入っており、事実上すべてのGoコードが同じように見えます。次のコードをgofmtに入れると、
package main
func main(){
x:=1
fmt.Println(x)
}
常にこう正規化されます。
package main
func main() {
x := 1
fmt.Println(x)
}
インデントはタブ、importは整列、中括弧の位置まで固定されます。gofumptはここからさらに進んで、不要な空行の削除、特定の慣用句の強制といった追加ルールを重ねます。
prettier — Webエコシステムの統一者
prettierはJavaScript、TypeScript、CSS、Markdownなどウェブエコシステム全般を統一しました。少数のオプション(行の長さ、セミコロン、引用符の種類)だけ提供し、残りはツールが決めます。この「意見はあるが完全に独裁的ではない」バランスが幅広い採用を導きました。
black — Pythonの妥協なし
blackのスローガンは有名です。「どんな色でも黒であればよい。」ユーザーが調整できるものはほとんどありません。行の長さくらいは変えられ、残りはすべて固定です。この極端な単純さがPythonコミュニティで大きな反響を得ました。
ruff — 速度が変えた勢力図
ruffはRustで書かれ、既存のPythonツールより数十倍速いです。しかもリンティングとフォーマッティングを一つのツールに統合しました。速度は単なる利便性ではありません。保存のたび、コミットのたびに即座に実行されるので、開発者はツールの存在をほとんど感じません。摩擦がなくなれば採用が容易になります。
フォーマッターとリンターの違い
ここでよく混同される概念を整理すべきです。フォーマッターとリンターは違います。
- **フォーマッター**はコードの*形*を変えます。インデント、改行、空白。コードの意味は絶対に変えません。
- **リンター**はコードの*内容*について警告します。使われていない変数、潜在的なバグ、アンチパターン、規約違反。
この違いを表で見ると明確です。
| 区分 | フォーマッター | リンター |
| --- | --- | --- |
| 対象 | コードの形 | コードの内容と品質 |
| 例 | インデント、改行 | 未使用変数、null危険 |
| 自動修正 | 常に(形のみ) | 一部(安全なものだけ) |
| 意味変更 | なし | ありうる(修正時に注意) |
| 失敗時 | 再フォーマット | 警告またはエラー |
境界が曖昧になる場合もあります。ruffのようにリンターとフォーマッターを統合したツールが増えています。しかし概念的には依然として区別するほうが安全です。フォーマッターの変更は常に安全ですが、リンターの自動修正は時に意味を変えうるので検討が必要です。
CI強制とpre-commit — 自動化の位置
フォーマッターが本当の力を発揮するには強制されなければなりません。開発者が「忘れて」フォーマットしなければ一貫性が壊れます。強制する位置は大きく三か所です。
開発者エディター ローカルコミット CIパイプライン
+---------------+ +---------------+ +---------------+
| 保存時フォーマット| --> | pre-commit | --> | fmt --check |
| (即時FB) | | (コミット遮断)| | (マージ遮断) |
+---------------+ +---------------+ +---------------+
最も柔らか 中間の関門 最後の砦
三か所を重ねて防御するのが理想的です。エディター保存時フォーマットは摩擦が最も少なく、pre-commitフックは誤ったフォーマットがコミットされるのを防ぎ、CIはどんな場合も通過させない最後の砦です。
CIではたいていフォーマットを「適用」せず「検査」だけします。次のように。
フォーマットがずれていれば0以外の終了コードで失敗
gofmt -l .
またはPython
ruff format --check .
`--check`モードはファイルを直さず「直すべきファイルがあるか」だけを判定します。ずれたファイルがあればCIが失敗し、開発者はローカルでフォーマットして再度プッシュします。CIが直接コードを直してコミットする方式もありますが、これは予期しないコミットを作り論争になりうるので慎重にすべきです。
pre-commitフックの設定例は次のとおりです。
repos:
- repo: local
hooks:
- id: format-check
name: format
entry: ruff format
language: system
types: [python]
チーム導入戦略
新しいフォーマッターを既存のコードベースに導入するのは思ったより厄介です。最大の障害は「大再フォーマット(the big reformat)」です。ツールを最初に適用するとリポジトリのほぼすべてのファイルが変わり、この巨大なコミットがgit blameの履歴を汚染します。
これを緩和する実務テクニックがあります。
- **単一再フォーマットコミット**: フォーマットだけを変えるコミットを一つ作り、他の変更と絶対に混ぜません。
- **blame無視設定**: gitがそのコミットをblameでスキップするよう無視ファイルに登録します。
- **段階的導入を避ける**: ファイルごとに少しずつフォーマットするとdiffがずっと汚くなります。一度に全部やるほうがよいです。
導入の順序をまとめると次のとおりです。
1. チームがツールと最小設定に合意します。
2. 単一コミットで全体を再フォーマットします。
3. blame無視ファイルにそのコミットを登録します。
4. pre-commitとCI検査を有効化します。
5. エディター保存時フォーマットをチームに案内します。
フォーマッターとコードレビューの関係
フォーマッターがコードレビューに与える影響は思ったより大きいです。先に述べたように、フォーマットが自動化されるとレビュアーはスタイル指摘から解放されます。これがレビューの質を根本的に変えます。
フォーマッターのないチームのレビューを想像してみましょう。Pull Requestごとに「ここのインデントが違いますね」「この括弧は次の行に」「空白を一つ取ってください」といったコメントが積み上がります。こうした指摘はたいてい正しいですが何の価値も生みません。レビュアーの時間と作成者の忍耐を消耗するだけです。もっと悪いのは、こうした些細な指摘に埋もれて本当に重要な問題、つまりロジック欠陥や設計問題が埋もれることです。
フォーマッターがこの層を完全に取り除くとレビューは本質に集中します。
| 項目 | フォーマッターなし | フォーマッターあり |
| --- | --- | --- |
| スタイルコメント | 多い | なし |
| diffノイズ | 大きい | 小さい |
| レビューの焦点 | 分散 | ロジック/設計 |
| 感情の消耗 | 大きい | 小さい |
特に「感情の消耗」の項目が重要です。スタイル指摘はしばしば個人的に受け取られます。作成者は「自分の好みが否定された」と感じ、レビュアーは「小言を言う人」になります。ツールがこの葛藤を代わりに引き受ければ、人間同士のレビューははるかに建設的で協力的になります。誰もgofmtに怒りません。
これがフォーマッターの隠れた価値です。フォーマッターは単にコードをきれいにするのを超えて、チームの人間関係を改善します。論争の種を取り除くことで人々が本当に重要な協業にエネルギーを使えるようにします。
フォーマット戦争の歴史 — どうやってここまで来たか
フォーマッターが勝利するまでの歴史を少し振り返ると現在をよりよく理解できます。ソフトウェアの初期から開発者はコードスタイルをめぐって争いました。この争いは些細に見えますが驚くほど激しかったのです。
最も有名な論争はインデントです。タブかスペースか、スペースなら2桁か4桁か。この問いは数十年間開発者を分断し、ミームと冗談の定番の題材になりました。中括弧を開く位置、行の最大長、セミコロンの有無も同じでした。
こうした論争の問題はそれに何の客観的な正解もないことにあります。ほとんどのスタイル選択は純粋に好みで、どちらも明確に優れていません。しかし正解がないからこそ、かえって論争が終わりませんでした。各自が自分の好みを正当化しようとし、チームは合意に至らないままエネルギーを消耗しました。
転換点は二つの気づきでした。第一に、スタイルの一貫性がスタイルの内容よりはるかに重要だということ。どんなスタイルでもチーム全体が一貫して使いさえすればほとんどの利点を得られます。第二に、その一貫性を人間が手で守るのは非現実的だということ。人間はミスをし忘れます。ツールだけが完璧な一貫性を強制できます。
この二つの気づきが出会って意見のあるフォーマッターが生まれました。gofmtが「論争せず一つに定めよう」と宣言したとき、それは単なるツールではなく文化的な宣言でした。そしてその宣言はこの10年間ソフトウェアの世界全体に広がりました。今日私たちがスタイル論争から自由なのはこの歴史の結果です。
決定論と冪等性 — 良いフォーマッターの条件
良いフォーマッターが備えるべき技術的性質が二つあります。決定論(determinism)と冪等性(idempotency)です。
**決定論**は同じ入力に常に同じ出力を出すという意味です。どの開発者の機械で回しても、いつ回しても結果が同一でなければなりません。もしフォーマッターが環境や時刻によって違う結果を出すなら、それは災難です。チームメンバーごとに違うフォーマットが出れば、そもそもフォーマッターを使う理由が消えます。
**冪等性**はすでにフォーマットされたコードを再びフォーマットしても変わらないという意味です。一度フォーマットした結果をまたフォーマットしてもそのままでなければなりません。次を考えてみましょう。
元コード --フォーマット--> 結果A --フォーマット--> 結果A (同一)
|
冪等性が壊れると
|
元コード --フォーマット--> 結果A --フォーマット--> 結果B (違う!)
冪等性が壊れたフォーマッターはCI検査で果てしない問題を引き起こします。開発者がローカルでフォーマットしてプッシュしたのに、CIのフォーマッターバージョンが微妙に違って再フォーマットが必要だと出れば、無限ループに陥ります。だからチーム全体がフォーマッターの正確に同じバージョンを固定して使うことが重要です。
この二つの性質のため、フォーマッターのバージョン管理は思ったより重要な問題です。多くのチームがフォーマッターのバージョンを依存関係ファイルに明示的に固定し、CIとローカルが正確に同じバージョンを使うよう強制します。
大規模コードベースでの性能
フォーマッターが遅ければ開発体験が悪くなります。保存のたびに数秒ずつ止まれば開発者はフォーマットを切りたくなります。ここでruffのようなツールがなぜ勢力図を変えたのかが見えてきます。
従来のPythonツールはPython自体で書かれて遅かったのです。一方ruffはRustで書かれて数十倍速いです。この速度差は単なる利便性を超えます。保存のたび、コミットのたびに実行されるツールが即座なら、開発者はその存在をほとんど感じず、摩擦がなくなれば抵抗なく採用されます。
性能が導入の成否を分ける状況をまとめると次のとおりです。
| 状況 | 遅いフォーマッター | 速いフォーマッター |
| --- | --- | --- |
| 保存時自動フォーマット | 遅延を体感、切りたくなる | 即座、無意識 |
| pre-commitフック | コミットごとに待機 | 一瞬 |
| 大規模CI検査 | パイプラインのボトルネック | 無視可能 |
| エディター統合 | タイピングを妨げる | 滑らか |
これが「速度も機能だ」という言葉が出る理由です。どんなに良いルールを持つツールでも遅ければ結局切られ、切られたツールは何の価値もありません。
フォーマット無視コメント — 脱出口のジレンマ
ほぼすべてのフォーマッターは特定の区域をフォーマットから除外する無視コメントを提供します。整列されたデータテーブルや意図的に配置したコードのように、自動フォーマットがかえって可読性を損なう場合のための脱出口です。
しかしこの脱出口はジレンマを生みます。無視コメントがなければフォーマッターが時に悪い結果を強制し、無視コメントが多くなればフォーマッターの一貫性という核心価値が崩れます。リポジトリのあちこちに無視コメントが散らばると、結局「どこはフォーマットされてどこはされない」という予測不可能な状態になります。
実務原則はこうです。無視コメントは本当にまれに、明確な理由があるときだけ使います。そしてなぜ無視するのか短い説明を一緒に付けます。無視コメントが増えるなら、それはフォーマッターが悪いのではなくコード構造に問題があるという信号かもしれません。
言語エコシステムごとの文化差
興味深いことに、フォーマッターに対する態度は言語エコシステムごとに違います。この違いは各言語の設計哲学とコミュニティ文化を反映します。
Goコミュニティは最初から「一つのフォーマット」を文化として受け入れました。gofmtにオプションがないことに誰も不平を言わず、むしろそれを誇りに思います。一方JavaScriptエコシステムは長らくスタイルの多様性が大きく、prettierが登場するまでチームごとにバラバラでした。Pythonはその中間あたりだったのが、blackとruffで急速に標準化されました。
この文化差は実務に示唆を与えます。新しい言語を導入するとき、そのエコシステムの標準フォーマッターが何か、コミュニティがどんな態度を持つかを把握すれば不要な論争を避けられます。標準が確固としたエコシステムではそれに従うのが最善で、標準が弱いエコシステムではチームが早く一つを定めることが重要です。
自動化の落とし穴と批判的視点
フォーマッターはおおむね祝福ですが落とし穴もあります。
**過度な厳格さの反作用。** ツールが厳格すぎると、時に可読性を損なう結果を強制します。例えばテーブルのように意図的に揃えたコードをフォーマッターが崩す場合があります。ほとんどのツールはこうした場合のためにフォーマット無視コメントを提供しますが、乱用するとツールの価値が消えます。
**リンタールールの無限膨張。** フォーマッターは論争をなくしますが、リンターはむしろ論争を増やしえます。「このルールをオンにするかどうか」をめぐってチームが延々と議論します。ルールセットが肥大化すると開発者は警告に鈍感になり、本当に重要な警告まで無視します。
**ツールが思考を代替するという錯覚。** フォーマットがきれいだからといってコードが良いわけではありません。フォーマッターは形を整えるだけで設計を改善しません。ツールに依存して「通ったから大丈夫」と考えると本当の問題を見逃します。
**設定ファイル管理の負担。** 柔軟なツールほど設定ファイルが大きくなり、その設定自体が保守対象になります。これがgofmtのような無設定ツールが魅力的な理由です。管理する設定がなければ設定をめぐって争うこともありません。
多言語リポジトリでのフォーマッティング
現代の多くのリポジトリは一つの言語だけではありません。バックエンドはGo、フロントエンドはTypeScript、インフラスクリプトはPython、設定はYAMLとJSON。こうした多言語リポジトリでは各言語ごとに違うフォーマッターを調整しなければならない問題が生じます。
各言語の標準フォーマッターが違うので、リポジトリ全体を一つのツールでフォーマットすることはできません。代わりに言語別フォーマッターを一つの統合された入口の後ろに集める方式を使います。
リポジトリフォーマットコマンド (一つ)
|
+--> Goファイル --> gofmt
+--> TSファイル --> prettier
+--> Python --> ruff
+--> YAML/JSON --> prettier
この構造で重要なのは開発者が言語ごとに違うコマンドを覚える必要がないことです。pre-commitフレームワークのようなツールがファイル種類を見て適切なフォーマッターを自動的に呼びます。開発者はただコミットすればよく、裏で各ファイルが正しいツールでフォーマットされます。
多言語リポジトリの落とし穴はツールバージョン管理が複雑になることです。複数の言語のフォーマッターをそれぞれ固定しCIとローカルで一致させなければならないので管理地点が増えます。このためツールバージョンを一か所で宣言するマニフェストを置き、すべての環境がそれを参照するようにするのがよいです。
リンタールールの三つの層
リンターをうまく使うにはルールをむやみに全部オンにするのではなく層に分けて考えるべきです。実務でリンタールールはおおよそ三つの層に分かれます。
- **エラー層**: ほぼ確実にバグであるもの。未使用変数、到達不能なコード、誤った比較。これらは強制するのが正しいです。
- **警告層**: たいてい悪いが例外があるもの。複雑度の高い関数、長い引数リスト。警告に留め強制はしません。
- **好み層**: 純粋に好みの問題であるもの。これらはたいていオンにしないほうがよいです。オンにすると論争だけが生じます。
この層を表にまとめると次のとおりです。
| 層 | 例 | 処理 |
| --- | --- | --- |
| エラー | 未使用変数、null危険 | CIで強制失敗 |
| 警告 | 高い複雑度、長い関数 | 表示するが通過 |
| 好み | 特定文法の好み | たいてい無効化 |
核心はエラー層だけを強制し、残りは慎重に扱うことです。すべてのルールをエラーで強制すると開発者は些細なことに足を取られ、すぐにリンター自体を回避しようとします。ルールセットは小さく明確なほど尊重されます。
レガシーコードベースへの導入
これまでの議論は新規プロジェクトを前提にしていました。しかし現実の多くのチームはすでに数年間スタイルが入り混じったレガシーコードベースを扱います。ここにフォーマッターを導入するのはより難しい問題です。
最大の恐怖は大再フォーマットが何かを壊すという懸念です。フォーマッターは形だけ変えるので原則として動作を変えませんが、ごくまれに例外があります。例えば文字列の中の空白や特定のマクロ処理で微妙な違いが出ることがあります。だから導入後に全体テストを回して回帰がないか確認することが必須です。
レガシー導入の安全な順序は次のとおりです。
1. フォーマッターをインストールするがまだどのファイルも変えません。
2. 検査モードで回してどれだけのファイルが変わるか規模を把握します。
3. テストスイートが十分か確認します。不足なら先に補強します。
4. 単一コミットで全体を再フォーマットします。
5. 全体テストを回して回帰がないことを確認します。
6. blame無視ファイルにそのコミットを登録します。
ここでテストスイートの重要性が明らかになります。テストが堅牢なら大再フォーマットが何かを壊したとき即座に捉えられます。テストが貧弱なら大再フォーマットは賭けになります。だから逆説的に、フォーマッター導入の前提条件がテストカバレッジである場合が多いのです。
もう一つの現実的な考慮は進行中のブランチです。大再フォーマットコミットはほぼすべてのファイルに触れるので、まだマージされていないブランチと大規模な衝突を起こします。だから大再フォーマットは進行中の作業が少ない時点(例: リリース直後)に行い、すべてのチームメンバーに事前告知してブランチを整理させるのがよいです。
フォーマッターができないこと — 命名と構造
フォーマッターの力を過大評価しないことが重要です。フォーマッターはコードの形を整えますがコードの質を改善しません。次の二つの関数を見てみましょう。
def f(x, y, z):
a = x + y
b = a * z
return b
このコードは完璧にフォーマットされています。インデントも空白も非の打ちどころがありません。しかし関数名`f`と変数名`a`、`b`は何も説明しません。フォーマッターはこの問題を絶対に直せません。命名、関数分解、抽象化レベルのような本当の設計問題は人間の判断の領域です。
これがフォーマッターとリンターを盲信してはいけない理由です。ツールを通過したコードが「十分に良い」という錯覚を植えると、肝心の命名と構造についての熟考が消えます。ツールは形の下限を保証するだけで、設計の上限を引き上げません。良いコードは依然として人間が作ります。
実務推奨事項
これまでの内容を実務指針に圧縮すると次のとおりです。
- 言語に標準フォーマッターがあればそれをそのまま使います。車輪を再発明しないでください。
- 設定は最小に。オプションを増やすほど論争が増えます。
- フォーマッターとリンターを概念的に区別し、それぞれの役割に忠実にさせます。
- CIでは適用ではなく検査だけします。
- 導入は単一再フォーマットコミットで、blame無視とともに。
- リンタールールは少数精鋭に保ってアラート疲れを防ぎます。
- ツールは形を整えるだけで設計を代わりにやらないことを覚えておきます。
エディター統合 — 摩擦をなくす最後の一片
フォーマッターがチームに定着するには開発者の日常ツールであるエディターに滑らかに統合されなければなりません。理想的な体験は開発者がフォーマッターの存在をほとんど意識しないことです。コードを書いて保存すれば自動で整理されます。別のコマンドを打つ必要も、ルールを覚える必要もありません。
エディター統合の核心的な方式は保存時フォーマット(format on save)です。ファイルを保存する瞬間フォーマッターが回ってコードを正規化します。こうすると開発者はスタイルを気にせずロジックだけに集中できます。
コード作成 (スタイル無関係に)
|
v
保存 (Ctrl+S / Cmd+S)
|
v
フォーマッター自動実行
|
v
正規化されたコードが画面に
ここで重要なのはチーム全体が同じエディター設定を共有することです。リポジトリにエディター設定ファイルをコミットしておけば、新しいチームメンバーがリポジトリを開くやいなや正しいフォーマット設定が適用されます。こうすると「自分のエディターでは違うようにフォーマットされる」という混乱を防げます。
ただし保存時フォーマットにも注意点があります。非常に大きなファイルでは保存が遅くなることがあり、他人のコードを開いて一行だけ直したのにファイル全体が再フォーマットされてdiffが大きくなる場合があります。後者は先に述べた単一再フォーマットコミットでリポジトリを事前に正規化しておけばほとんど解決します。
フォーマッターの未来 — 統合と知能化
フォーマッターツールの進化方向は二つに要約されます。統合と知能化です。
**統合**の流れはruffがよく示しています。以前はフォーマッター、リンター、インポート整列器がそれぞれ別個のツールでした。それぞれをインストールし設定しCIに付けなければなりませんでした。ruffはこれらを一つに合わせて設定と実行を単純化しました。ツールが少ないほど管理負担が減り一貫性が高まります。この統合の流れは他の言語エコシステムにも広がる可能性が大きいです。
**知能化**の流れはまだ初期です。従来のフォーマッターは純粋にルールベースです。しかしAIがコードスタイルを学習してチームの慣行を自動的に把握し、ルールで明示しにくい微妙なスタイルまで合わせる方向が議論されます。ただしここにはフォーマッターの根本要求である決定論と冪等性が障害になります。AIの確率的な性質が「同じ入力に同じ出力」という原則と衝突するからです。
だから当分フォーマッターの核心は依然として決定論的なルールベースでしょう。AIはルールを提案したり例外的なケースを扱う補助的な役割に留まる可能性が大きいです。フォーマッターに関しては予測可能性が柔軟性よりはるかに重要な価値だからです。
おわりに
意見のあるフォーマッターの台頭はソフトウェア文化の成熟を示しています。私たちはスタイル論争が何の価値も生まないことを学び、その論争をツールに委ねることで本当に重要な問題に集中できるようになりました。gofmtが始めた「オプションなし」の哲学は今や複数の言語エコシステムに広がりました。
しかしツールが論争をなくしてくれるからといって判断までなくしてくれるわけではありません。フォーマッターは形を定め、リンターは落とし穴を警告しますが、良い設計と明確なコードは依然として人間の仕事です。ツールが得意なことはツールに任せ、人はツールが届かないところにエネルギーを使うこと。これが意見のあるツールが私たちに与える本当の贈り物です。
スタイルをめぐって争うのに使う時間を、これからはより良いソフトウェアを作るのに使いましょう。
参考資料
- Hacker News: https://news.ycombinator.com/
- GeekNews (Hada): https://news.hada.io/
- gofmt (Go公式): https://pkg.go.dev/cmd/gofmt
- gofumpt リポジトリ: https://github.com/mvdan/gofumpt
- Prettier 公式ドキュメント: https://prettier.io/docs/en/
- Black 公式ドキュメント: https://black.readthedocs.io/
- Ruff 公式ドキュメント: https://docs.astral.sh/ruff/
- pre-commit フレームワーク: https://pre-commit.com/
현재 단락 (1/204)
2026年前半、GeekNewsとHacker Newsでコードフォーマッターの話題が再び盛り上がりました。gofmtより厳格な「意見のある(opinionated)」ツールであるgofumptが注目...