I am an unholy, evil tab user. I am unrepetant. And now I will try to convert you to my evil ways.
Contents
The Holy War
There is a holy war about indentation in programming, split between two camps, those who use tabs and those who use spaces.
This somewhat oversimplifies things, because there are multiple ways to indent with both tabs and spaces, but we'll discuss
that in Style below.
And let me start by saying that I fully recognize that the
masses are not on my side.
I realize that, for example, in one
of my favorite programming languages, Ruby, the unbelievable majority of programmers use spaces for indentation.
If you think the masses are generally correct and should be followed without question, then this article is not for you.
Also, it should be noted that while I do prefer tabs, I will not override whatever project I am working on - we certainly
don't want to mix tabs and spaces in source for the same program. But if you are working on a project that I started
or am in charge of, get ready for the tabs!
Notation
Since we're arguing about whitespace, here's how I'll show spaces and tabs in code examples so we can visualize and discuss.
Every two spaces will be shown with a '. ' - as per the following code:
. . 10.times {
. . . . puts "I believe in indenting using 4 spaces per level!"
. . }
And tabs will be represented with '→', as per this code:
→ 10.times {
→ → puts "Each level of indentation is a tab"
→ }
Style
Let's be clear about what tab indentation we are talking about. I use tabs for indentation and spaces for alignment.
What horror! Did you say you are mixing tabs and spaces?
No, not for indentation. That would be the way of madness. But one of the issues with trying to use tabs is if you have multiline code/comments that need to be aligned, i.e.:
→ 10.times {
→ → i = i + 1 # I really like to increment numbers,
→ → → → # and here I use the terrible variable name of 'i'
→ }
This will only render properly if we use a specific tabstop, and that's a ridiculous requirement that ruins
the entire point of using tabs. And this all happened because we confused indentation with alignment. That
second comment line is not supposed to be four levels of indentation, it's supposed to be 2, like the line above,
and then spaced over for alignment purposes. We don't use tabs between our words in the code, we just
use it for indentation. So since we are clever enough to understand the distinction between indentation and
alingment, the correct tab-indentation style would be:
→ 10.times {
→ → i = i + 1 # I really like to increment numbers,
→ → . . . . . # and here I use the terrible variable name of 'i'
→ }
Rationale
Let's look at a host of reasons to use tabs:
-
Typing a bunch of spaces is ridiculous. Many programmers use the tab key to get the correct
levels of indentation and then have their editor automatically convert that to spaces.
-
We lose information. It's trivial to convert tabs to spaces. Converting spaces to tabs
correctly to match the correct tab style isn't always trivial/possible
because information is lost. The beautiful thing is that you can set your editors
tabstop to whatever you think is the correct number of spaces and pretend that there are no
tabs in the file. I won't tell anyone.
-
Speaking of "number of spaces" - how many spaces? Ruby is 2 spaces by majority
consensus, whereas for PHP, you "MUST" use 4 spaces, and for the linux kernel,
one of the most important community code bases of all history, the standard is
8 spaces. So what does this tell us? This tells us that if you switch code
bases, now you have to switch your number of spaces. And that also tells us
that people have widely different preferences for how big indentation is
in terms of "readability".
Or you could just use tabs, and set the tabstop to whatever value you like.
-
Speaking of the size of indentation, consider programmers with vision issues.
I know of a project which had two programmers with vision issues, one wanted
8 space indentation because they needed assistance seeing the levels of
indentation, whereas the other programmer used a huge font and wanted indentation
of only 1 space because they effectively had little screen space. How do you
support them? You can't just have them convert the indentation, because information
is lost. It's not always clear which spaces are for indentation and which are for tabs.
-
Choice is good, not bad. There is no value in forcing every programmer
to see the same thing on their screen as you see, what matters is that we
have the same content. We do not, for example, enforce the font,
font size and font color our teammates work on the source code with because
it is irrelevant to the issue and a matter of preference.
I like to use the equivalent of 2 spaces for my indentation. And if
code uses tabs, then I can view everything as 2 spaces. If Linus Torvalds
(who mandated the 8 spaces of indentation on the linux kernel) wants to
join my project, he can set the tabstop to 8 spaces. Everybody gets what
they want.
-
Speaking of indentation size preferences, this isn't necessarily a static thing.
There are plenty of times where I will 'explode' my tabstop out to 8 or such
if I want to get a really clear idea of indentation over (unfortunately) long stretches
of code. I have a hotkey that can pop to 8 and back to 2 and so forth, and I use
it all the time. Choice and flexibility is good.
Why Spaces
Now let's look at a bunch of reasons to use spaces for indentation instead of tabs:
Note: The above section may have looked blank, but it should be noted that it actually contained 186 spaces.
Anti-Tab Arguments
I've seen a bunch of anti-tab arguments, I have yet to understand the reasoning behind any of them.
- "Tabs aren't consistent!"
-
The biggest argument I hear about why to use spaces is also the most baffling. Tabs are completely consistent - one level
of indentation is one tab. There is a rant against tabs that states "there is no guarantee that the code you’ve written will be read the same way".
And the problem with people being able to choose how their text is formatted is what, exactly?
- "Rendering isn't consistent!"
-
This is a good thing. Why do you care what the size of indentation is on my screen
when I look at code? You demand that I use spaces to be consistent so rendering
is consistent on all screens? Okay, I want two spaces whether you like it or not,
and I require that you use a blue font on a white background with the font
"JetBrainsMono NF" size 14 and a window size of 110x63, because I need the rendering to be consistent.
- "Sometimes errors refer to columns, not just line numbers"
-
Right - and this is consistent. What editor are you using that is confused
about how to count characters? This isn't unicode.
- "Everyone uses spaces!"
-
Worst argument for adopting a practice ever.
- "Code diffs are broken"
-
% diff --initial-tab ...
% diff --expand-tabs ..