[UPDATE: I just got an email from someone saying they use tabs over spaces because visually aligning everything by repeatedly pressing the spacebar is too cumbersome. That is not what is meant by using spaces over tabs! Every IDE/editor supports replacing tab presses with a dynamic and variable number of spaces until you get to the appropriate indentation level. It would be insane if this misunderstanding turned out to be one of the cruxes of the issue.]
I never really understood the Tabs vs Spaces debate. When I first started programming I started using tabs but almost immediately realized they just weren’t suited for the job. They promise flexibility but, in practice, that flexibility is largely a lie and you tie other developers to your indentation style regardless. If you are tying developers in to a style, then why use tabs which can add unexpected confusion?
In the examples below, tab characters are colored a darker grey. Don’t get hung up on the coding style, the issues of alignment are what’s important and the code is terse for example’s sake.
Tabs with 4 char widths
This example shows an initial setup that uses a 4-width tab for nearly everything. It looks great and beautiful when you are set up for a 4-width tab, but try changing the tab width with the buttons below the example.
All the careful alignment goes to crap when you change the tab width. Yes, the fact that you can change the tab width is a great option to have, but if it requires you to reformat your code then it is not actually a real feature of using tabs, it’s the same situation in any scenario. Either manual or automatic reformatting all around.
Tabs with 2 char widths
Below is the same example as above, but optimized for a 2 character width tab. The exact same problem applies, but you can also see that it takes a different number of tabs to produce similar alignments.
Tabs for block indent only
The last entry on our tabstop tour is an example that only uses tabs for block level indentation, which some people use as a solution to the above problems. This still has its own issues when alignments occur across block level indentations (look at the last block) but also raises the simple question “why?” Block level indentation is the simplest thing for an IDE to take control over, and the actual act of block indentation is almost always hidden from the developer. It is also the easiest to reformat globally since the rules for that are relatively standard, configurable in most decent IDEs or, at the least, tolerable.
Even if this is the most tolerable solution, it introduces yet another wrench into enforcing style with other developers. Now you need to make sure a developer only uses tabs for block level indentation, and spaces for alignment purposes.
Spaces for tabs, two character indent
And here is the example that doesn’t include tabs at all, just spaces and a 2 tab indentation level. The benefit here is unmistakable intent.
There is no chance for confusion and what you see is what you get.
Contributors/teams do still need to set a common config as to the number of spaces for indentation, but that is better than assuming you don’t need to do that with tabs and getting conflicting code style regardless.
Personally, it really doesn’t matter to me as long as there is a standard. If you use tabs, then you still need to add the tab width you are coding with to coding guidelines. The reason I use spaces is because the environment is self-describing. If you see two spaces, you know the guideline is a two character indentation level. If you see a tab and effed up alignment, you need to experiment with a few configurations in order to find the style the original developers were coding towards.
(and yes, “flexible” or “smart” tabs sound awesome, but are impractical in mixed environments where IDE/editor support is so spotty)