Wednesday, April 07, 2010

Why tabs are better

I'm tired of this stupid "tabs vs. spaces" code style debate. Tabs win hands down on just about every measure. Anyone still laboring under the misapprehension that it makes sense to indent one's source file using spaces should consider the following:
  1. Line-based comments (‘//’, ‘#’) at the head of the line don’t screw up the indentation (unless tab depth <= 2).
  2. You can change the indentation depth without editing the file. This is a huge feature, folks. If I like shallow indentation on all my source, I can make it so, and people who prefer the other extreme are not affected. The counter-argument (put forth by Checkstyle, among others) that one should not be required to set tab depth in order to read source is absurd; tab depth is always set to something, whether you like it or not (see 11), and code indented using tabs is readable regardless of the setting, unless tab depth is ridiculously high. The only code that actually does require a fixed tab depth to be legible is code that mixes tabs and spaces, which I encounter all too often. See 10.
  3. Spaces-based indentation will inevitably become inconsistent because no one can agree on his/her favorite indentation depth (see 2).
  4. Indentation mistakes are more obvious using tabs (unless tab depth = 1, which is just stupid).
  5. Tab indentation characters, when used properly, are more semantically relevant than spaces.
  6. Files are smaller (relevant especially for Javascript, CSS, HTML).
  7. Fewer keystrokes are needed to navigate within source files. Sorry, but “Ctrl+Right arrow” is two keystrokes, plus you have to hold one of them down.
  8. Making tabbed whitespace visible in an IDE is useful for eyeballing how things line up; making spaces visible is useful for “magic eye”.
  9. Tabs are unable to support the unreadable, but nevertheless default, function-call line-break style of making parameters line up with the opening ‘(’. Remember, it is a feature that this abomination is not supportable. Unfortunately it is still possible to put just the first parameter on the same line as the ‘(’, but no indentation choice can prevent that bad decision.
  10. If you have to edit a production config file using terminal-based default emacs, should you really be checking that in? I should add that the indentation used by default in Emacs (and pervasive in high-profile source such as the JDK) is a horrific hybrid of spaces and tabs which actually does force you to set your tab depth to a fixed value of 8 in order to read code thus indented. See 2.
  11. Some well-known tools (e.g., ReviewBoard) typically display tabs with a depth of 8, which is kind of high. I claim that this tab discrimination is also a feature, because it discourages deeply-nested code which is a good thing.

The only moderately sane argument in favor of spaces is that the code "always looks the same". Isn't that nice. You can write comments that use little "^^^^" to point to something on the line above. Wow. I guess that's worth throwing out points 1-11.

I'm not going to wade into the quagmire of my other personal code style choices. But it's time this debate, which rages again and again every time I join a new team, be permanently put to bed.


cowtowncoder said...


Only one comment: I think you published this couple days too late!

PhiLho said...

Alas, it seems the space indentation people are more numerous, for some unknown reason. Or are they just louder?

- Tabs are dead easy to convert to spaces, the reverse isn't necessarily true (particularly if number of spaces is inconsistent!).
- I dislike when a dumb editor forces me to type backspace n times to unindent. It cannot happen with tabs!

The only drawback, as noted, is that lot of display environments (terminal, browsers, etc.) adhere to the old convention of tab = 8 spaces and doesn't allow to change this setting.

And one thing I hate the most, like you, is when people doesn't change their settings when editing a file, resulting in an odd mix of spaces and tabs for indentation. A sad example of this can be seen when you look at the Java library sources.