• Coding
  • Tabs vs Space, it does matter

Tabs vs Spaces is a small battle in the greater Indentation War. This is a silly
debate, one of the little annoyances a programmer comes across once in a
while. We each have a preference and none of us understands how anyone can think
differently. It sounds meaningless and petty, but as soon as you start working
with other people's files, indentation gets all messed up, and version control
logs go insane, this stuff matters.

Superficially, everyone seems to agree: "It doesn't matter which, just pick one
already. The problem is only mixed environments." Some groups have already tried
to enforce one: Makefiles and YAML force you to indent with tabs. Python
strongly suggests you use 4 spaces.

I think this choice is important, clearly, that's the object of this post. I'm
not looking to force anyone to change their habits, simply taking a look at the
implications of each alternative. To a greater extent, this choice says a lot
about what kind of programmer you are.

Why tabs?

Isn't it obvious? Tabs aren't a character to print, as much as a markup language
to signal indentation to the screen. In this string, "name\taddress\tphone
number", I'm creating a CSV variant with the "indentation" character as a
separator. That adds syntactic meaning to the text. In that aspect, indenting
with spaces sounds like another terrible habit in another markup language.

The advantages of giving syntactic meaning to your code are plenty. The
immediate effects come from helping your text editor understand your text
better. Sure, most editors have some sort of macro that says:
"WHITESPACES=' \t\n\r'" or something. But that is limiting.

A text editor that understands your text, can come up with wonderful features
like IntelliJ or the amazing magic of emacs. It also allows for better Static
code analysis and other formal proofs.

I'm not saying that space indentation is necessarily an obstacle. But if you
think that all this is important, tabs is the obvious choice.

Why not tabs?

I blame text editors. In a perfect world, everyone would agree that tabs make
more sense. It's safe to assume that almost every keyboard around has a tab key,
yet tabs are still hectic, awkward and messy.

The options for configuring proper tab display aren't always well defined, often
too hidden under series of menus and clicks. emacs and vim are targeted at power
users, but what about nano or pico? What about those GUI editors that mask the
features to take advantage of this markup?

Empirically, I noticed that a lot of people feel more comfortable removing tabs
altogether, going as far as programming their tab keys to insert a number of
spaces instead. Their attitude seems to say: "Tabs is a feature I could do well
without. It's important that everyone should be able to participate, space
indentation is a safer hack".

Why does it matter?

"Safer hack". This is a heavy one. A lot of issues of the programming world can
be resumed to this: "Powerful" vs "Safe". I can think of plenty: garbage
collections, dynamic typing, functional programming, just to name a few. It
seems to me that this can be generalized to "Getting things right" vs "Getting
things done". On some level, these are the two main conflicting motivations for
programming.

I don't have an absolute solutions for the matter, just a personnal
preference. I'm not implying that Python prefers the "Safe" mindset, I'm only
saying that I prefer the use of tabs for the same reason the C programmer
prefers manual memory management, the Lisp hacker enjoys dynamic typing and the
Haskell scientist likes the functional purity. I like "Power", not "Safe".

Which do you prefer?
If you take Visual Studio 20xx, it automatically indents as soon as you leave the line you are working on. Only in very few cases it messes up with the indentations. Basically when you remove a bigger if statement that has lots of inner lines of code.

I've always thought indentation was merely for visual preference rather than an actual safeguard against something. Especially with the programming languages that use braces.

For example:
if{
while{
if{
<.......>
}}}

if{
    while{
             if{
                   <.......>
               }
           }
  }
It is much more easier to know the braces while indenting than stacking them altogether.

As choosing the type of indentation, i prefer tabs than spaces, because it is more tidy and easier to backspace from it.
One of the first things I do when getting a new text editor is setting up "soft tabs" (i.e., tabs become spaces). When writing Ruby, JavaScript or HTML, I set the tab size to 2. In CSS, I set it up to 4, since there's not much nesting involved, unless you're writing LESS.
I don't like soft tabs, they don't play along well with REAL tabs :D
I like my tabs, unfortunately, C# converts (prefers) spaces for some reason.
I think tabs make sense, especially with indentation.
arithma wroteI like my tabs, unfortunately, C# converts (prefers) spaces for some reason.
Reason:

Yeah, but I don't like to be the odd ball. Defaults matter.
samer wroteOne of the first things I do when getting a new text editor is setting up "soft tabs" (i.e., tabs become spaces). When writing Ruby, JavaScript or HTML, I set the tab size to 2. In CSS, I set it up to 4, since there's not much nesting involved, unless you're writing LESS.
And then I pull from your code, and I run a diff to see what you changed. And I get a bazillion false positives. And I wonder why my code appears all wrong.

Arrrrrgh.
@rahmu: this raises a good point about coding conventions. It would make sense to agree on these things before-hand when working on a team project.
Excellent article, rahmu. You're right that there's no One True Way. Instead, some guidelines:

1. If I'm working on someone else's code, I use their style.
For example, the linux kernel enforces an indent style of tabs for indentation, and a tabstop of 8 columns.
vim: noexpandtab, tabstop=8, softtabstop=0, shiftwidth=8
2. If I'm working on my own code, I use my own tab style consistently, no exceptions.
I like indenting with spaces only, where one indentation level is 4 spaces.
vim: expandtab, tabstop=8, softtabstop=4, shiftwidth=4
What about when working with other people on a project? My recommendation is:

Agree on a style. Use a pre-commit hook.

The idea is simple. Everyone has their favorite editor and indent style that feels comfortable visually. You don't want to make your fellow programmers uncomfortable by imposing a style that they don't like. Unhappy programmers produce unhappy code. Instead, each programmer just uses the indent style and settings they like in their own editors.

When they commit their changes, your version control system's pre-commit hook runs and automatically re-indents the code to match the style you all agreed upon. All the code in source control is in the same style, diffs make sense. Whenever someone checks out the code, their editor will reformat it in their own style (in vim, I would just type :retab).

There are tools that do this:

* GNU Indent: C
* astyle: C, C++, C#, Java
* perltidy: Perl
* phptidy: PHP
* gofmt: Go

I could go on, but you get the point. It's simple, you set it up once, and no one has to change their habits.
a year later
I have been obsessing over this topic lately. I love using hard tabs, the're clearly superior than spaces and of course I have them reduced to a size of 4 instead of 8. But one problem with hard tabs is that in your editor it might be set to 4 while many others read it as 8, including collaboration websites such as Github as 8 is the standard which makes the code look horribly indented. Moreover sharing code on forums would also look bad on most syntax highlighters, unless they're set to deal with tabs.

I think I'll start using soft tabs with size 4 from now on and totally forget about hard tabs, spaces will always keep you on the safe side...
is this still an issue these? vs, sublime, pydev, all of them do the job for you, but if i have to choose, i'd pick tabs, because when you're writing fast you might hit 5 spaces without noticing, there's no way to hit 2 tabs and not notice that.