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

コードのフォーマットは不要であるべきだ

2025年9月8日原文(maxleiter.com)

概要

  • コードフォーマット問題 は1980年代に既に解決されていた事実
  • Ada開発環境Rational R1000 の先進的機能紹介
  • DIANA IR によるテキストソース非保存方式
  • 現在でも フォーマット論争が続く現状 への疑問提起
  • 参考文献リンクとさらなる考察

コードフォーマット問題の歴史とAdaの先進性

  • コードフォーマット に関する議論は、実は 1980年代 に既に解決済みの課題
  • 高校時代の Mr. Paige (Adaコンパイラ開発経験者)による指摘
  • Ada開発環境 では、テキストソースを保存せず DIANA(Descriptive Intermediate Attributed Notation for Ada) という中間表現を利用
  • 各開発者が 好みの整形設定 でコード閲覧可能な仕組み
  • Rational R1000 ワークステーションの特徴
    • インクリメンタルコンパイル
    • セマンティック解析
    • バージョン管理
    • 統合デバッグ機能
  • Xerox Alto のようなワークステーションだが、Smalltalkではなく Ada を利用

DIANAとR1000の革新性

  • R1000 ではテキストソースを保存せず、 DIANA 形式でプログラムを管理
  • コンパイラとIDE がDIANAを直接理解し、任意の整形で表示可能
  • スペースとタブ による整形の違いが無意味化
  • プログラムツリー直接編集 (現代でいう projectional editing
  • Grady Booch による要約
    • 「R1000は事実上DIANAマシンだった。ソースコードはDIANAツリーの整形表示に過ぎなかった」
  • フォーマット論争やlinter問題 が発生しない開発環境

DIANA利用の追加メリット

  • ハードウェアアクセラレーション によるDIANA処理
  • インクリメンタルコンパイル (強い型付け言語では当時画期的)
  • 容易なリファクタリング ("refactoring"という言葉が生まれる前)
  • 高速な統合 (大規模Adaシステム開発に必須)

現代との比較と課題意識

  • 現在では ハードウェアアクセラレーション は不要、 リファクタリングツール も進化
  • しかし フォーマット問題 ではむしろ後退
  • projectional editing やライブ環境の普及は進まず
  • 現代の開発パラダイム に合った新しい解決策の模索が必要

参考文献・さらなる情報

  • Experiences with Code Generation (1985)
    • https://www2.eecs.berkeley.edu/Pubs/TechRpts/1985/CSD-85-249.pdf
  • Ada Compiler Validation Summary Report: Rational Environment (1985)
    • https://apps.dtic.mil/sti/tr/pdf/ADA157830.pdf
  • Grady Booch’s blog post about the 5th anniversary on Rational's acquisition (2008)
    • https://web.archive.org/web/20160304051102/https://www.ibm.com/developerworks/community/blogs/gradybooch/entry/rational_anniversary?lang=en#pagePlaceBar

Hackerたちの意見

ここでのトレードオフは、ソースファイルとやり取りするためのユニバーサルなツールセットが使えないことだね。テキスト以外のものだと、grepやdiff、sed、バージョン管理があまり効果的じゃなくなる。結局、専門的なツールやフォーマット、IDEの拡張に縛られちゃうんだよね。一方で、Unixの哲学はプレーンテキストとの組み合わせを重視してる。フォーマットの議論を切り裂くハサミがあるとしたら、もし選んだエディタで初期のスペース幅が設定できたら、タブを好む人たちは他に何か言い訳があるのかな?

OS全体がこれらのソースファイルを中心に構築されてるんだよね。一方で、Unixの哲学は「プレーンテキスト」を解析するコードが組み込まれたツールが設計されて初めて「繁栄」するんだ。

その通り。こういうアイデアは何度も出てくるけど、コストと利益が全然合わないんだよね。シンプルなフォーマッターを使うのを避けるために、信じられないほど複雑なツールを追加してるだけだし。全ての開発者が自分の好みでコードを見れることなんて、そんなに重要じゃないと思う。私が関わったチームでは、標準のスタイルガイドを使って、フォーマッターで強制してるけど、全員が全てのルールに同意するわけじゃない。それでも、慣れちゃうんだよね。コードのフォーマットについて議論したりこだわったりするのは、単なる無駄なバイクシェディングだと思う。

もし共通の中間エンコーディングがテキストで、バイナリじゃなかったらどうなる?そうすればgrepやdiff、sedはまだ使えるよね。ASTに基づいて動作するフォーマッティングツールがあれば、チェックインされたコードは特定のASTのための標準的な形式にできる。エディタはASTを解析して、ユーザーの選択した異なるフォーマットでソースを表示し、ファイルをディスクに書き込むときに標準形式に変換できるんだ。

DIANA irから元のソースコードみたいな形に戻すことってできるの?その逆変換の結果をgrepしたりできるし…

ソースを標準フォーマットで保存して、各開発者に合わせて unpack するなら…なんで標準フォーマットが普通のソースコードでなきゃいけないの?全てのツールはテキストバックエンドでも存在できるし、grepやsedのサポートもタダでついてくるよ!

もし初期のスペース幅が好きなエディタで設定できるなら、タブを好む人たちは他に何か意見があるのかな?もちろんあるよ。だってタブ幅は動的に柔軟だから、初期のスペース幅だけじゃ足りないんだ。

Grepやdiff、sed、行ベースの非セマンティックマージは、コードを操作するにはひどいツールだよ… それらでさらに深みにハマるより、何かもっと良いものを考える理由があった方がいいかもね。

これが機能するイメージは、gitフィルターみたいな感じだね。バージョン管理からチェックアウトすると、好みのフォーマットでテキストに変換されて、それを期待通りに扱うことができる。ステージングすると、保存された表現に変換される。gitでは、これはsmudgeとcleanフィルターを使って行われる、git LFSのようにね。フォージやその類のためのビューアもあって、必要に応じて保存された表現を解釈するように作られてる。テキストで作業するけど、そのテキストは標準の保存表現じゃない。構造が変わった時だけdiffが出てくる。事前コミットのリンターフックでもほとんど同じメリットが得られるけどね。

テキスト以外のものは、grepやdiff、sed、バージョン管理をあまり効果的にしないよね。UNIXの設計ミスかもしれないけど、テキストにこだわりすぎてる気がする。

テキストは確かに重要なポイントだけど、私たちが短期的な視野で谷に入ることを避けているせいで、ローカルな問題にハマっていると思う。あなたの例は構造的な知識があるコードに対してはうまく機能するよね:- grep: シンボル検索(テキストのgrepより100倍使ってる)や https://github.com/ast-grep/ast-grep - diff: https://semanticdiff.com(他にもいろいろ)、つまり:ノイズの多い構文の変更を隠して、移動したコードを捉えようとする。投影プログラミングがあれば、コードが移動することの表現力がもっと高くなると思う。- sed: https://npmjs.com/package/@codemod/cli - バージョン管理:Unisonのような言語を見て、ここでできる面白いことを探るのがいいと思う。特にライブラリに関しては。一般的な例としては、非意味的な変更(順序の変更や無関係な空白など)による競合がないこと。

面白い読み物だね。なんで表示されるものが保存されたアーティファクトと同じである必要があるのか、ずっと疑問に思ってた。git diffみたいなものも、ソースのIRのプロジェクションを通して見れるべきだと思う。treesitterみたいなものがあると、ASTやIRのための効率的で効果的なHCIがどうなるか、夢想することもあるよ。f#の順序付きコンパイルみたいなものは、コードレビューを簡単にしてくれるけど、それは中間形式の一部(依存関係の順序)が一級のアイテムとして見えるからなんだ。もっと緩い順序要件のコードの小さな変更を考えるよりも、ずっとシンプルに感じるよ。そういう場合、diffや関連するインターフェース、抽象クラス、実装を行ったり来たりして、デルタがプログラム全体にどんな影響を与えているのか理解するのが大変なんだ。

Hacker Newsで議論の続きを見る