… and why I can’t just let it go.
Before I say which is better, I want to explain why I think the issue is even important. Whitespace is ignored by the compiler so it’s purely for readability. It’s there for you. Variable names have meaning and describe the intention of code. Similarly, whitespace describes the structure of a program.
Suppose there is a hypothetical programmer who is intelligent and writes correct programs, but he names his variables things like “var1” and “var2.” In real life, most code needs to be modified at some point, through no fault of the original programmer. Requirements change. When another developer (or even the original programmer) needs to read this code, he will find it utterly useless. He will waste lots of time trying to understand it. He may even re-implement some existing functionality simply because he couldn’t find it buried there in the obfuscated code. I would go so far as to say this hypothetical programmer deserves to be fired simply for his unusual naming style.
Code with inconsistent indentation isn’t so useless – fortunately for us it is easily repaired by automatic formatting tools. However, leaving a file with inconsistent indention puts that burden on next person who reads it. The next reader will take slightly longer to mentally parse the file since he must figure out scope information which the indentation level could have communicated. And someone will eventually need to fix it, manually or with a code beautifier.
On the one hand, I feel like a programmer who can’t indent his source consistently also can’t be trusted to make the proper design and engineering decisions made while implementing even the smallest feature. In reality, I know that most code is already not indented consistently. Even if it was, accidents do happen. A merge tool or a terminal editor may easily cause inconsistencies that would have never happened in the IDE, for example. Thus to truly have a standard, it must be enforced externally – by the IDE on check-in, or better yet by the version control system.
Now the controversial part: Tabs are better than spaces.
There – I’ve said it. Here’s why. With either choice, a standard is being imposed on all the developers who work on the project. But choosing spaces really forces two separate things – the ASCII character used for indentation plus the width of the indentation. Choosing tabs only imposes the ASCII character used for indentation, which is the absolute minimum needed to have a standard.
A common argument is that if you use spaces, it looks the same in any editor without doing any extra configuration. But in order to have a standard, you must do extra configuration. Otherwise the first time you hit the tab key, you may introduce an inconsistency. If you use vim with the default configuration, you just inserted a tab. Emacs is worse – it inserts a mix of tabs and spaces by default. And I’m sure another editor inserts spaces by default.
An alternate suggestion is to never use the tab key, but that can’t be enforced. It shouldn’t be anyway because tapping the space bar is a waste of time. Like I said, a real standard must be enforced by the version control system. As long as a standard is being imposed, it should be tabbed indentation so that each teammate may configure his editor to use the width he prefers. Each teammate must configure his editor, or else waste more time fixing the whitespace when the version control system rejects his check-ins.
There is a second argument in favor of tabs that is extremely simple. Have you ever seen a file that was indented with 4 spaces in some parts and 2 spaces in other parts? Two coders who use tabs could never interfere with each other in this way.