Murga

個人的に言いたいコト・主張・気持ち。

なんでインデントは4スペースなんだ?2スペースはどうして生まれた?タブインデント見かけなくなったね?

コーディングにおける、タブやスペース文字でのインデントに関する疑問。

自分は CSS を勉強し始めた頃にどこかで見かけたタブインデントを真似し始め、その後 HTML を書く時に1スペースインデントを取り入れ、Java を知ってからは4スペースインデントを使い、JavaScript を本格的に書くようになってから現在は2スペースインデントを使っている。

タブを使うかスペースを使うか、という好みはともかく、そもそも何で「スペースが4つ」とか「スペースが2つ」とかいうルールが出来たのだろう、という歴史的経緯を知りたく、調べてみた。

個人的な意見:2スペース派

歴史的経緯はともかく、現時点で自分がどう思っているかという意見を書いておく。バイアスがかかってるかもしれないしね。

  • 基本2スペース派
    • フロントエンドの人間なので、フロントエンドで馴染みが深いのは2スペースかな
    • Python も2スペースにルールを上書きして書く
    • 1スペースより幅が取れて可読性が良く、4スペースより省スペースで、程よい幅だと思っている
  • タブ文字が混ざると、ブロックコメント内のインデントがキモい気がしている
function hoge() {
  /* ほげ  ← ココは2スペース
   * ふが  ← この行のインデント!!ココだけ「3スペース」になるのだが、タブを組み合わせるより自然な気がしている
   */
}
  • IDE (VSCode) を使えば、タブキー1回でで2スペース打ったり、1回の Delete キーで2スペース消せたりもできるので、不便していない
  • カーソル移動も2スペース単位で動けるし
  • タブ文字は表示幅の設定をしないとキモくて見づらいが、スペースなら必ずその幅で見えるから気持ち良い
  • 2スペースは全角文字1文字の幅と一致させられるので日本語が混じった時も扱いやすい
  • HTML およびウェブ上でコードを扱う時に、タブ文字はテキストエリアでタイプできず、半角スペースは行頭にあると表示時に無視され、どちらも一長一短

個人的にはそんな感覚があって2スペース派であるが、好みや優劣ではなく、それぞれの手法が生まれた歴史的経緯を知りたいというのが今回の趣旨である。

タブインデント・8スペースインデントの起源

Is there any historical reason for 8 space ? I don't know.

I guess something to do with reading a byte. Like you know, if you know that block comprises of 8 spaces, you replace that with 1 byte while storing. Just a wild guess.

8スペースは1バイト換算して扱えるから歴史的に重宝されていた過去があったりするかも?という推測。


Despite five characters being the typical paragraph indentation on typewriters at that time, the horizontal tab size of eight evolved because as a power of two it was easier to calculate with the limited digital electronics available.

Using this size tab to indent code results in much white space on the left, so most text editors for code, such as IDEs, allow the size of the tab to be changed, and some (in particular on Windows) default to four instead of eight.

Disagreements between programmers about what size tabs are correct (and whether to use tabs at all) are common.

Modern editors usually have Tab key insert the indentation the programmer wants as spaces or combinations of tabs and spaces.

英 Wikipedia の記述。タイプライターに装備されたタブは5スペース分で表現されるのが主流だったが、2の累乗である 8 のスペースとして扱う方が、古いデジタル環境では都合が良かったという話。なるほど前述の推測が当たっていた。


というワケで、タイプライターのタブ機能をコンピュータに持ち込むにあたって、デジタルで扱いやすい8スペース分として取り扱うようになったのが、一番最初の歴史的経緯であろう。


Some programmers such as Jamie Zawinski state that spaces instead of tabs increase cross-platform portability.

Others, such as the writers of the WordPress coding standards state the opposite, that hard tabs increase portability.

タブ文字は OS 間で扱いが異なり、可搬性に乏しいという意見があったようだ。ただコレも、タブなら良い、スペースなら良い、というのは宗教論争状態らしいが。

いずれにせよ、タブ文字の代用として8スペースが登場したと思われるのは、納得かな。

タブインデント・8スペースインデントの利点

資源が乏しい時代に扱いやすかった、という理由で採択された「1タブ = 8スペース」だが、副次的な効果も見い出されている。

Linux カーネルのコーディングスタイルでは、8スペース分の幅を取るタブ文字をインデントに使うことが書かれている。

  • 8スペース分もあるとインデントが深くなった時に見づらいって?そもそもインデントが深いコードの方が間違ってんだよ
  • 8スペースでインデントされてても読みやすい平易なコードを書け
  • 8スペースでインデントされてれば、そういう臭いコードにすぐ気が付けるだろ?

といった趣旨だ。なるほど、逆にインデントを深くさせないための工夫として8スペース (分のタブ文字) を使わせるワケだ。


もう少し現代に寄って、スペースインデントとの比較で論じている人も。

  • 参考:Python: using 4 spaces for indentation. Why? - Stack Overflow
    • スペース文字はインデント以外にも使われるが、タブならインデントのみを表現する文字として切り分けられる
    • タブなら表示時に文字幅を設定できる
    • 「1インデント = 1タブ文字」ならスペースを連打するよりキーストロークが少なく済む
    • 「1インデント足す」は「1タブ文字を入力」、「1インデント削る」なら「1回 Delete キーを押す」だけで、インデントを追加・削除する時も理にかなっている
    • スペース文字を多用すると、タブインデントと比べてソースコードのファイルサイズが多くなる

タブインデントの方がスペースでのインデントより理にかなっていることが多いよ、という意見。確かに納得できる。

ただ、最近の IDE やビルドシステムを考えれば、それを利点として扱うほどのことはないかな、という感じ。逆に「IDE がないような環境でも読み書きせにゃならん」という、イマドキからすると逆に特殊な環境であれば、タブ文字の方が汎用性は高いのかも。

昔はこうしたデータサイズや入力効率なんかが、生産性に物凄く響いていたってことね。

4スペース・2スペースが登場した理由

そんなタブ・8スペースの時代から、どうして4スペースや2スペースが登場したのか、というところを調べてみる。

8スペースだとインデントが深すぎて辛いよ、奇数よりはキリが良いよ、という理由で何となく生まれたのかな、という推測は立つが、もう少し起源を調べてみた。

4スペースを広めたのは Java の Sun だという話。そうなのか。確かに Java は4スペースが多い気がするが。Python だと def_ (末尾はスペース) の4文字と、インデントの4スペースが一致するから気持ち良い、という意見も見かけた。w

2スペースは JS 界隈のコールバック地獄に対応するため主流になったとか。確かに、インデントを増やさざるを得ない構文上の問題があったと思う。

あと私見だが、HTML はどうしても入れ子 (ネスト) で構造を表現するので、より狭いインデント幅が好まれたのかなと思う。自分が CSS を勉強し始めた2004年頃なんかは、HTML は4スペースとかで、CSS はタブインデント、みたいな人も多かった気がする。で、JS の2スペースに合わせて、フロントエンド界隈はまるっと2スペースに置き換わったのかと。

ネタ:フィボナッチ・インデント

void foo()
{
 foo { /* 1 space */
   bar { /* 3 spaces (1 + 2) */
      baz { /* 6 spaces (1 + 2 + 3) */
           qux { /* 11 spaces (1 + 2 + 3 + 5) */
                   foobar { /* 19 spaces (1 + 2 + 3 + 5 + 8) */
           }
      }
   }
 }
}

インデントが深いのはよくない!でも浅いインデントは許してほしい、という考えに一番合っているのかも。w

現在の多数派はスペース

GitHub の40万リポジトリを調査した結果、ほぼ全ての言語でタブよりスペースが多かったとのこと。タブ派の方が多かったのは C 言語と Go 言語だけだったそうで。

まとめ

以上、自分が調べた限りでの、歴史的経緯をざっくりまとめる。

  • タイプライターでインデントを表現していた「タブ」の概念が、コンピュータにも移植された (元々のタブは5スペース程度の幅だった)
  • タブ文字として移植された際、2の累乗で表現しやすい8スペース分として扱うことにした (データ量の削減にも繋げられたと思われる)
  • タブ文字は OS 間の可搬性が良くなかったのか、代替として8スペースが登場した (スペースをインデントに使う文化が生まれる)
  • Java などの高級言語で、タブが8スペース分の幅を取っていると鬱陶しくなり、4スペース派が登場した (特に Sun が広めた説がある)
  • HTML は構造上ネストが多く、JavaScript には「コールバック地獄」があったことから、フロントエンド界隈ではさらに2スペース派が主流になった

…こんな感じかな。

Linux カーネルだったり、Sun だったり、Google だったりといった権威がコーディングスタイルを定めると、それに準拠する人が増えるのだろう。慣例だったものが標準化されたのか、標準化されたから慣例になったのかはよく分からないところも多かったが、結局はみな好みで決まったことなのかなと思う。

その他参考文献