I notice several people have been referred to this page from http://derkarl.org/why_to_tabs.html, which tries to counter my arguments against tabs. (I also notice that the author rather ungracefully failed to inform me of the page's existence, thereby conveniently not giving me a chance to respond. Kind of makes his rather immature "I win again" comment a bit hollow ...) Well, he raises some interesting points, but fails to address some of mine. Or maybe he just didn't understand them, which is probably my fault, because I admit that some of the arguments below aren't worded in a particularly clear way. When I get some time, I'll attempt to fix this, and respond to his article with some concrete examples which clarify what I mean.
Anyway, back to the original page...
Many people intermingle hard tabs (ASCII 09) with spaces in their source code, rather than using n spaces in the place of a single tab, where n is usually 8. It's a matter of personal taste, but here's why I don't believe this is a good idea in general. (I say `in general' because there are always exceptions -- in my opinion the following applies especially to free software because in the bazaar model of development, code exposure is very high. However, if for example you are unfortunate enough to be working for a company which leaves none of its employees any choice as to their code indentation style and editor, then well ... this document is irrelevant anyway :-)
It makes context/unified diffs far harder to read, because of the way they use the first column to indication the manner in which the line has changed. This is a pretty important point for many coders these days. Even if you're not collaborating with others on your code, how certain are you that no-one else will ever want to look at it or modify it and maybe even send you patches? UPDATE: I just found out that diff provides two possible workarounds for this problem: --expand-tabs and --initial-tab. Neither are entirely satisfactory though.
It makes re-indenting sections more difficult; if for example you try to shift a block two columns right, it might have no effect on lines starting with tabs. Decent editors do automatic indentation anyway of course, but there are often circumstances (especially in Perl, where even GNU emacs can't always parse the syntax correctly) when they don't do the right thing. And again, how certain are you no-one else will want to re-indent blocks of your code at a later point? Very certain? Really? You're sure you're never even going to copy and paste a fragment of the code into an email? (Think what happens when someone else replies to that email.)
`tabs are good because then you can choose your own tab width'argument doesn't work because:
Tabs aren't just used at the beginning of lines. There might be a left-aligned, multi-line comment to the right of a block of code, e.g. consider this real-life example, found in /usr/include/gmp.h on a FreeBSD box:
typedef struct { int _mp_alloc; /* Number of *limbs* allocated and pointed to by the D field. */ int _mp_size; /* abs(SIZE) is the number of limbs the last field points to. If SIZE is negative this is a negative number. */ mp_limb_t *_mp_d; /* Pointer to the limbs. */ } __mpz_struct;
Or consider someone who is on an 80x25 terminal and decides they want to view some multiples-of-8 tab-indented code with 2 or 3 column indentation, because all the 8 space tabs are forcing loads of the code to wrap onto the next line (or off the screen), decreasing readability. They type less -x2 foo.pl, and bam, suddenly any such rectangular comment blocks to the right of the code are no longer left-aligned -- it's a mess.
There can be problems even if tabs only occur at the beginning of lines. For example, say that some code was written in emacs with tab width set to 8 spaces, but the indentation style is Kernighan & Ritchie, which has basic indentation 5 spaces wide. If emacs is set to use tabs, lines indented one level will start with 5 spaces, and lines indented two levels will start with one tab followed by two spaces (8 + 2 == 10). If someone else tries to view this code setting their editor/pager tab width to 4, first level lines will be indented 5 columns, second level lines 6 columns, third level lines 11 columns ... oops!
The same argument can be applied to spaces. Want to view source with 2 column indents using 4 column indents? No problem:
$ perl -pe 's/^(( )+)/$1$1/' foo.c | less
Want to change source with 8 column indents to use 3 column indents? No problem either:
$ perl -pi -e 's/^( +)\1{7}/$1 x 3/e' foo.c
Obviously a simple Perl script or editor hooks can be written to make such transformations more convenient to use.
I'm always interested to hear other people's views on this. Are there other reasons I've missed? Or perhaps you'd like to try to convince me I'm wrong! I'm an open-minded person, so if you can argue the opposite case strongly enough, I'll change this page and my coding habits. Otherwise...
Do the world a favour! Put this in your ~/.emacs:
(setq-default indent-tabs-mode nil)
or this in your ~/.vimrc:
:set expandtab
(Someone please tell me how this can be achieved in other editors.)
The demi-god Linus has his own, rather er, religious views, some of which I agree with.
Dawn Endico has pointed out that Jamie Zawinski of Netscape/Mozilla fame has also written a web page on this topic which presents a similar argument to mine, but in a different way. Well worth a look. Thanks Dawn!
Someone who didn't give his name sent me a whole bunch of related links. I'm relieved to see that these pages mostly agree with me :-)
Robert Swindell pointed out an excellent proposal called PT/SC whereby formatting parameters (e.g. tab width) are stored in the header of a plain text file using a common, humanly-readable syntax. Thanks Robert. Let's hope that editors implement support for this soon ...
Last updated: Sun May 2 12:54:37 2004
© 1995-2003
Adam Spiers <adam@spiers.net>