TABs vs. Spaces

Perhaps the classic holy war in computing is whether to use TABs in your source code. Most people don't really care anymore, and do whatever everyone else is doing (consistency in group projects is important). While the general industrial trend is for spaces, I want to come down strongly for TABs: you should use TABs to indent and spaces to separate and align.

The most obvious reason is that it's correct, in the sense of lexical semantics. TABs were literally invented for indentation. Spaces are for spacing things. You wouldn't use a TAB between words in a sentence, because that's the wrong character. Similarly, you shouldn't use spaces to indent your code, because that's the wrong character.


There are a few other benefits you get for free:

  • You can adjust the indentation width in your editor for all the code, at-once, on-the-fly. Some people prefer a width of four characters. Some people, less-correctly, prefer two or eight. Some people like to watch the world burn, and use three, or other peculiar widths. It doesn't matter—they can configure their TAB display widths and everything will come through as they please. This is a great boon for collaboration!
  • It is much-harder to accidentally misindent code. With spaces, one-space errors are common and often go unnoticed. Whereas, with TABs, given that most people choose a TAB width greater than one, a misindented line is off by the full TAB width, making its incorrect indentation immediately obvious.
  • Fewer keypresses—to input, delete, or skip over.
  • Typical source files become significantly smaller. This can be hugely significant on the web, where e.g. HTML code is downloaded to display the page (albeit minification is a thing).
  • Similarly, in purely-interpreted languages, fewer characters will run faster.
  • Similarly, in compiled languages, a smaller file size means it is faster to parse and therefore compile.

But the main thing I want you to take away, regardless of whether you ultimately agree or disagree with my suggestion to use TABs, is the indisputable fact: spaces are lexically incorrect for indentation. You are free to continue using them, with any justification you please, just so long as you remember this.


Using TABs FAQ

Now, I'll address some archetypal arguments from the other side. I intend to be exhaustive; if you have additional objections, please send them to me.


Why should I expend the effort to switch over?

So that you're not using the lexically wrong indentation character and can reap the additional benefits listed above to boot.


TABs have different widths on different platforms! My code won't look the same![1]

Yes, and that is a good thing. People have different display preferences[2]. They may even require, in an accessibility sense, a different indentation width to make sense of your code.


It doesn't work! My code becomes misaligned.

Then you're doing it wrong. A typical example runs like:

....int function(int arg0,
.................int arg1);

with the result supposedly looking incorrect if TABs are used. But, remember, TABs to indent, spaces to align and space. There is a mixture of both here. The correct way (for this terrible coding standard) would be:

   int function(int arg0,
   .............int arg1);

That doesn't work because TABs aren't just used at the beginning of lines![1]

Again, use TABs to indent, spaces to align and space. If you erroneously use TABs to do aligned spacing, then sure, you'll get problems. This comes up as a strawman argument a lot, so let me repeat: do not use TABs to do alignment or spacing.

In any case, putting comments, the main use-case for mass-TAB/space-intraline-spam, on the same line leads to very long lines and messier code, and so you shouldn't be doing that anyway.

   // Incorrect usage of TABs for spacing/alignment.  Unacceptable!
   int function(int arg0,       // This is a multiline comment.
   .............int arg1);→→      // Messy and long lines.
   // Correct usage of spaces for spacing/alignment.  Acceptable.
   int function(int arg0,..........// This is a multiline comment.
   .............int arg1);.........// Messy and long lines.
   // Better commenting and layout.  My preferred solution.
   // This is now a single-line comment.  Simple, short lines.
   int function(
      int arg0,
      int arg1
   );

TABs are lexically for tabulating, not indentation![3]

That is incorrect. TABs are lexically for both, and in-fact the primary semantics now is indentation because tabulation via embedded text is largely obsolete as a typographical concept.

The very first commercial typewriters had a bewildering variety of keyboard layouts, and generally only one spacing key. The TAB key was patented in the year 1900 with the purpose of moving the carriage to the next TAB Stop (i.e. column). You'd set the TAB stop one tick over for paragraph indents, and could use several ticks in various ways to make tables.

Thus the task of spacing was separated from indentation and tabulation, and all three problems were resolved at once. Therefore, TAB was invented for the purpose of indentation and for tabulation, and this purpose has remained unchanged since the literal Victorian age.

By the time the TAB key was introduced for computers (sometime around 1980, it seems), the primitive software at the time didn't support anything for it but indentation, which is anyway a far-more-common task than separating table columns (even more-so today, since tabulation is typically handled by features of the environment, not its text).

ASCII (adopted by ISO 646 which punts to ECMA 48 on the matter) states (§8.3.60[4]):

HT indicates the beginning of a string of text which is to be positioned within a line

. . . alongside language about the underlying datastream implying that this offsetting can be generalized for tabulation. So this is true for computers as-well, and is embedded in our most fundamental standards.

There is a good summary of software interpretations at ([5]), configuration thereof at ([6]), and at least one alternative replacement ([7]) proposed, but the general concept of "move over to the next column somehow" seems clear, and this clearly makes its modern application be indentation (also to (some kinds of) alignment, though we reject this because of the problem discussed in the previous FAQ entry).

In any case, it should be clear that spaces aren't meant for either purpose.


Mixing TABs and spaces is dirty!

Why? Good code is both indented and spaced. If you think the combination is dirty, then either don't indent your code (supported in many languages) or don't separate your words (not supported by most languages)—but I think it's obvious the result will be dirtier. What's dirty is deliberately using the wrong character for the wrong task, and somehow thinking it a virtue.


Using TABs is difficult! Mixing TABs and spaces is difficult!

Please what? It's easier. You hit the indent key to indent. You hit the space key to space. No more reformatting files by your coworkers just so you can stand to look at them. No more counting spaces to check for misindentation. No more pounding the spacebar 32 times for each line (or binding the TAB key to lie to you to partially automate that process).

If one seriously cannot separate whitespace into trivial categories (understanding the difference between spacing, indentation, line breaks, etc.), how can one possibly expect to deal with actually-difficult semantics, like the actual programming you're trying to do in the first place?


TABs make the source too wide to read[8]! My lines are wrapping!

So configure their display width smaller. Problem solved. By the way, with spaces, you'd have been stuck with it.


Lisp has a gazillion indent levels, and TABs are too wide!

Again, configure their display width smaller. Problem solved—and more flexibly than with spaces, too.

It's also worth noting that it is good style (in both functional and imperative languages) to avoid deep nesting anyway. Pull things out into reusable functions and/or negate logic.

Probably the only reason you'd have made this objection in the first place is you're using an archaic 80-column coding standard. You can fit three side-by-side editors at a more comfortable 100-ish characters each[9] on a modern bargain-bin display, and many developers have 2+ screens. There's just no reason to persist in using DOS-era widths.


YAML is space-only, so we must use spaces everywhere![10]

Amplifying YAML's mistake doesn't transmute it into a non-mistake. It's unnecessary anyway; typical editors support different settings for different languages. I think there might even be a few languages that are TAB-only, just to make the whole concept totally intractable.

(By the way, YAML is underspecified and therefore gets handled inconsistently between parsers, while its complexity makes it slower computationally, and complete implementations rare. Ironically, YAML's reason for forbidding TABs is supposedly consistency. Consider using TOML (or JSON) instead.)


With spaces, I can do half-sized indents, like for public: in a class definition![11]

That is, obviously, an abomination.


TABs make diffs harder because the first character is a + or - in a diff!

That would be a problem with that tool not making the correct distinction between an annotation for a line and the line itself (although if so, I think it would look better with TABs anyway), but in any case the complaint is unsubstantiated since the problem does not occur in said tool, and moreover there are better tools for computing and presenting differences anyway.


Emacs doesn't understand TABs!

If that were true (and it is not), then I'd get a better editor. You should absolutely demand that every editor you use is competent at editing at-minimum UTF-8 text—and frankly ASCII, of which TAB is an integral part, is so fundamental to modern computing that not supporting it is unthinkable.

I do not know of any text editor people actually use that doesn't support TABs, although I know a quite a few that support it incorrectly (caused, no doubt, by the ignorance of their space-using authors). However, the major text editors support it just fine—from vi to Visual Studio. Maybe this complaint had substance 30 years ago, but it doesn't today.


Some tools I could imagine existing load space-indented files as TABs and save them back as spaces. So, let's all use spaces, but you can still be happy?

Even aside from the question of whether such tools exist, are integrated with major editors, and are reliable—all three of which are outstanding questions with answers generally trending toward 'no'—from a technical perspective, converting TABs to spaces is far-easier than converting from spaces to TABs—it doesn't require any parsing or understanding of the source language! In other words, we might do this the other way round: everyone uses TABs, and by presenting TABs as spaces in editors, the space-indent users might be happy. (Though we shouldn't do that either, for all the other reasons discussed.)

Code representation, code presentation, and coding standard are three distinct concepts. Sure, the near-future dream is autoformatting editor workflows that are capable of totally disentangling them: you load the code into your editor, and the editor parses it and formats it according to your personal preferred style, so everyone can hack on code exactly the way they want. But that's the point—what people want. The code representation might be gzipped binary on disk without any line breaks, or even tagged LLVM IR.

The whole point of inventing these tools isn't to lie to TAB users or space users, but to give people the freedom to understand code in the clearest way possible. Whereas you're thinking to use it to beat your own mistaken sensibilities into people you have power over.


Famous people and popular languages prefer spaces![12]

And there are famous people and popular languages that don't.

Regardless, this is a mere argument from authority, and does nothing to refute the simple fact that spaces are still the wrong indentation character.

Also, the space-indenting authorities disagree! For example, Linus Torvalds vehemently wants 8-character indentation[13] while Guido van Rossum wants 4-character indentation[14]. If they used TABs instead, they could collaborate while both using their preferred indentation widths!


My company / collaborators / manager / standards document / religion requires me to use spaces, so your argument is irrelevant!

Irrelevant, maybe, but not incorrect.

It is the unfortunate truth that, driven by the loud myopia of spaces-users, the industry is converging against TABs. Many coding standards, and even some tools, are being built to require spaces—and there are plenty of well-meaning senior programmers mandating spaces as "good practice" without having ever thought about the issue at all.

If you're one of those people, please do reconsider. Collaboration and consistency are important, and when you mandate something, you need to make sure it's the right thing.

Spaces are objectively wrong at the lexical level, and TABs bring all the practical advantages.


Notes, Sources, and Further Reading

Note: Citation of sources given are not necessarily selected as primary sources, nor even as particularly significant. They are selected merely as being an instance of the topic at-hand I can point to.


Return to the list of blog posts.