On Preferring Spaces Over Tabs in PHP

By | March 15, 2012

The best lack all conviction, while the worst are full of passionate intensity. — “The Second Coming”, William Butler Yeats

Keep the above in mind when considering either side of the debate. ;-)

tl;dr

Herein I assert and discuss the following:

  • Using spaces has subtle advantages over using tabs in collaborative environments.

  • The “tabs reduce file size” argument is factually true, but is a case of optimizing on the wrong resource.

  • The “tabs allow each developer to set his own indent widths” argument sounds good in theory but leads to problems in practice regarding line length recognition and inter-line alignment.

Introduction

In the PHP world, there are effectively two competing indenting practices: “4-spaces” and “tab.” (There are some in the 2-space camp as well but they are very few.)

I want to point out a couple things about why spaces might be considered preferable in a collaborative environment when style is important on a PHP project. And yes, it turns out this dicussion does matter.

I used to use tabs, and slowly migrated over to spaces. Over the course of several years, I have found there is a slight but useful advantage to using spaces for indentation when working with other developers, and I want to discuss that one advantage in this essay.

Note that I am not asserting an overwhemling, absolutely obvious, infallible moral rule that clearly favors spaces over tabs as the One True Path. It is merely a noticeable improvement regarding more sophisticated rules of style.

Do I expect this essay to change anybody’s mind on using tabs? No; but, I do hope it will give some food for thought.

Regarding Tabs

When making an argument, it is important to state the alternative viewpoint in a way so that people who hold that viewpoint actually agree with it.

What are the reasons for preferring a tab indent? As far as I can tell, they are:

  • The tab is a single character, so files are smaller.

  • Using a tab character allows each developer to change the level of indent
    that he sees, without actually modifying the on-disk file.

If there are other reasons I have missed, please let me know.

File Size

In general, I assert that the “file size” argument is a case of “optimizing on the wrong resource.”

By way of example, let’s take one file from a real project that uses 4-space indenting, Zend_Db_Abstract, and use wc -c to count the number of bytes in the file.

$ wc -c Abstract.php
40953 Abstract.php

Now, let’s convert each 4-space indent to a tab.

$ unexpand -t 4 Abstract.php > Abstract-tabs.php
$ wc -c Abstract-tabs.php
34632 Abstract-tabs.php

We save 6K of space on a 40K file, or roughly 15%, by using a tab character for indents instead of a 4-space indent.

Now, to get an idea of how that compares to another way to reduce size, let’s remove all the comments from the original 4-space file and see what that does. We’ll use a tool I found after two minutes of Googling (you may need to change the hashbang line of remccoms3.sed to point to your sed):

$ wget http://sed.sourceforge.net/grabbag/scripts/remccoms3.sed
$ chmod +x remccoms3.sed
$ ./remccoms3.sed Abstract.php > Abstract-no-comments.php
$ wc -c Abstract-no-comments.php
21022 Abstract-no-comments.php

That’s about a 50% reduction. If disk storage is really a concern, we’d be much better off to remove comments than to convert spaces to tabs. Of course, we could do both.

This example makes me believe that the “file size” argument, while factually correct, is a case of “optimizing on the wrong resource.” That is, the argument gives strong consideration to a low-value item. Disk space is pretty cheap, after all.

A followup argument about this is usually, “Even so, it’s less for the PHP interpreter to deal with. Fewer characters means faster code.” Well, not exactly. Whitespace is tokenized, so the parser sees it all the same.

Developer Tab Stop Preferences

This, to me, seems to be the primary argument for preferring tabs over spaces for indenting. Essentially, the idea is to allow each individual developer on a project to make the code look the way that individual developer prefers.

This is a non-trivial argument. It’s very appealing for the individual developers to be able to work on a project where Developer A sees a tab stop every 4 characters, and Developer B sees a tab stop every 2 or 8 or whatever characters, without changing the actual bytes on disk.

I have two arguments against this; they seem to be minor, until we examine them in practice:

  • It becomes difficult to recognize line-length violations with over-wide tab stop settings.

  • Under sophisticated style guides, inter-line alignment for readability becomes inconsistent between developers using different tab stops.

These arguments require a little exposition.

Line Length Recognition

Because of limitations of this blog, let’s say that our coding style guide has a line length limit of 40 characters. (I know, that’s half or less of what it should be, but it serves as an easy illustration.)

The following code, with 4-character tab stops, shows what that line length limit looks like:

         1         2         3         4
1234567890123456789012345678901234567890
function funcFoo()
{
    $varname = '12' . funcBar() . '34';
}

It’s clearly within the line length limit. But it looks like this under an 8-character tab stop:

         1         2         3         4
1234567890123456789012345678901234567890123
function funcFoo()
{
        $varname = '12' . funcBar() . '34';
}

A developer who sees this code under 8-character stops will think the line is past the limit, and attempt to reformat it in some way. After that reformatting, the developer working with 4-character tab stops will think the line is too short, and reformat it back to being longer. This is not particularly productive.

Some will say this just shows that line length limits are dumb. I disagree.

Inter-Line Alignment

By “inter-line alignment” I mean the practice where, if we have several lines of code that are similar, we align the corresponding parts of each line in columns. To be clear, it’s not that unaligned code is impossible to read; it’s just noticeably easier to read when it’s aligned.

Typically, inter-line alignment is applied to variable assignment. For example, the following unaligned code …

$foo = 'bar';
$bazdib = 'gir';
$zim = 'irk';

… is easier to scan in columns aligned on the = sign:

$foo    = 'bar';
$bazdib = 'gir';
$zim    = 'irk';

We can see clearly what the variables are in the one column, and what the assigned values are in the next column.

Alternatively, we may need to break an over-long line across several lines, and make it glaringly obvious during even a cursory scan that it’s all one statement.

Now, let’s say we have a bit of code that should be aligned across two or more lines, whether for readability or to adhere to a line length limit. We begin with this contrived example using 4-space indents (the spaces are indicated by • characters):

function funcName()
{
••••$varname = '1234' . aVeryLongFunctionName() . 'foo' . otherFunction();
}

Under a style guide where we align on = to keep within a line length limit, we can do so regardless of tab stops:

function funcName()
{
••••$varname = '1234' . aVeryLongFunctionName()
•••••••••••• . 'foo' . otherFunction();
}

Under a guide where we use tabs, and Developer A uses 4-character tab stops, we need to push the alignment out to the tab stops to line things up (tabs are indicated by → characters):

function funcName()
{
→   $varname→   = '1234' . aVeryLongFunctionName()
→   →   →   →   . 'foo' . otherFunction();
}

However, if a Developer B uses an 8-character tab stop, the same code looks like this on Developer B’s terminal:

function funcName()
{
→       $varname→       = '1234' . aVeryLongFunctionName()
→       →       →       →       . 'foo' . otherFunction();
}

The second example has the same tabbing as in the first example, but the alignment looks broken under 8-character tab stops. Developers who prefer the 8-character stop are likely to try to reformat that code to make it look right on their terminal. That, in turn, will make it look broken for those developers who prefer a 4-character stop.

Thus, the argument that “each developer can set tab stops wherever he likes” is fine in theory, but is flawed in practice.

The first response to alignment arguments is generally: “Use tabs for indenting and spaces for alignment.” Let’s try that.

First, a 4-character tab stop indent, followed by spaces for alignment:

function funcName()
{
→   $varname = '1234' . aVeryLongFunctionName()
→   •••••••• . 'foo' . otherFunction();
}

Now, an 8-character tab stop indent, followed by spaces for alignment:

function funcName()
{
→       $varname = '1234' . aVeryLongFunctionName()
→       •••••••• . 'foo' . otherFunction();
}

That looks OK, right? Sure … until a developer, through habit (and we are creatures of habit) hits the tab key for alignment when he should have used spaces. They are both invisible, so the developer won’t notice on his own terminal — it will only be noticed by developers with other tab stop preferences. It is the same problem as before: misalignment under the different tab stop preferences of different developers.

The general response at this point is to modify the tab-oriented style guide to disallow that kind of inter-line alignment. I suppose that is reasonable if we are committed to using tabs, but I find code of that sort to be less readable overall.

Solution: Use Spaces Instead

The solution to these subtle and sophisticated issues, for me and for lots of other PHP developers, is to use spaces for indentation and alignment. All professional text editor software allows what are called “soft tabs” where pressing the tab key inserts a user-defined number of spaces. When using spaces for indentation and alignment, all code looks the same everywhere, and does not mess up alignment under different tab stop preferences of different developers.

Conclusion

I realize this is a point of religious fervor among developers. Even though I have a preference for spaces, I am not a spaces zealot. This post is not evangelism; it is a dissection of the subtle and long-term issues related to tabs-vs-spaces discovered only after years of professional collaboration.

Please feel free to leave comments, criticism, etc. Because this is such a touchy subject, please be especially careful to be civil and maintain a respectful tone in the comments. If you have a very long comment, please consider pinging/tracking this post with a blog entry of your own, instead of commenting directly. I reserve the right to do as I wish with uncivil commentary.

Thanks for reading, all!

32 thoughts on “On Preferring Spaces Over Tabs in PHP

  1. Sean Coates

    I almost hate to even comment on this post (-:

    > … is easier to scan in columns aligned on the = sign:

    I’ve come to the firm belief that this is simply not worth it. Aligning isn’t actually important in practice (for me at least), and aligning causes two problems:

    1) the indenting issue you mentioned
    and
    2) non-semantic diffs/changesets in version control

    The solution to #1 is simply: never indent beyond the first non-whitespace character in a line. Sure, you lose alignment, but I really don’t think this matters (maybe you do, but I suggest you try code without alignment for a while, and if you’re like me, you’ll see that it doesn’t matter).

    #2 is kind of difficult, but here’s an example that I hope helps.

    Let’s say you have:

    $apple = 'red';
    $orange = 'orange';
    $banana = 'yellow';

    …then, one day, you decide to start supporting watermelons:


    $apple = 'red';
    $orange = 'orange';
    $banana = 'yellow';
    $watermelon = 'green';

    Ok, so apple has a weird whitespace. We can either unalign it:


    $apple = 'red';
    $orange = 'orange';
    $banana = 'yellow';
    $watermelon = 'green';

    … or realign everything:


    $apple = 'red';
    $orange = 'orange';
    $banana = 'yellow';
    $watermelon = 'green';

    In both cases, the diff shows whitespace changes. Non-lazy developers will commit whitespace changes in a different changeset than semantic changes, but… well… I don’t think I know any non-lazy developers.

    So, I’ve come to the conclusion that alignment should not be done. I’m sure people will disagree. That’s how it goes. (-:

    Your line-length argument is a good one. I hadn’t considered that in my adoption of tabs. I’m not convinced that it’s much better than the file-size argument, though (which I don’t think actually matters).

    Flamewar: begin! (-:

    S

    Reply
  2. Sean Coates

    Sadly, this blogging software removed sequential whitespace in my {code} blocks, so my comment makes little sense.

    Reply
  3. Tom

    I wouldn’t say 2 spacers are all that rare. For example, it’s part of the Drupal coding standard so at least anyone working in any depth with that CMS should be using it. When I worked with that for a while it became second nature and I’ve ended up adopting it all over the place. I just find it readable, spatially concise and inefficient in terms of visual real estate, and just quicker and easier to work with than 4 spaces, when you find yourself having to move through them. Having said that, I’m not so attached to it that I’d change if I had to. You need to be flexible. And, if you have direct colleagues, using whatever your co-workers are using is going to be the simplest way forward in the long run.

    Reply
  4. pmjones Post author

    @Tom: Regarding 2-spaces in Drupal, that’s fair. I suppose I should have said something like “among style guide recommendations” to point out that it’s about the guides, not the developers.

    Reply
  5. pmjones Post author

    @Sean: “Your line-length argument is a good one. I hadn’t considered that in my adoption of tabs. I’m not convinced that it’s much better than the file-size argument, though (which I don’t think actually matters).”

    Yeah, the line-length recognition is secondary to the alignment thing. It’s important, but not *as* important as alignment.

    Reply
  6. Hari K T

    Good post :-) . Space is always good for some editors as you mentioned is 8 for tabs , some is using 4.
    Normally we can set to change to spaces when a tab is pressed. So it seems an easy way for the developer still can use tabs :-) .

    Reply
  7. Timothy Warren

    My pet peeve with spaces is not adding a ‘tab’, but removing one. I have to remove 2, or 4 characters (or whatever) instead of 1.

    Also…aren’t eight-unit tabstops quite old-fashioned?

    Reply
  8. pmjones Post author

    @Timothy: Yes, I can see where that’d be annoying. Perhaps I have been spoiled by TextMate and similar modern text editors, which recognizes 4-space “soft” tabs and removes all 4 spaces when I backspace over one. I believe Vim and Emacs allow you to embed configuration rules for that kind of thing, but that might be more effort than one is willing to expend.

    Reply
  9. true type

    I have used a netbook with a very small screen for coding (great for coding on the commute). Using tabstops means I can set the indent on that machine much smaller and therefore see more code on the screen.

    I also use a true type font in my editors instead of a monospaced font as it’s much easier to read and uses less width (again useful for small screens). Using spaces to line up with characters of variable width means that I loose the alignment anyway.

    Line length limits should be a guide only – It’s there for a good reason but I’ve been in situations where white space in code matters and arbitrary new lines have caused issues(e.g. it causes artefacts in nested elements in IE). Besides, good editors can auto wrap long lines based on your personal preferences or detected screen width (this includes terminal based editors). Again on my netbook this was set to a smaller limit than on my desktop.

    So you can see how tabs instead of spaces and flexible line limits are much better for the reader. In this case the user (me) is king instead of the content and I can bend the content to my will. Spaces enforces the will of the many to the detriment of the few, where, in this highly technical and malleable world, it is not necessary.

    Reply
  10. Richard Ayotte

    One thing that wasn’t mentionned is the ease of code navigation. With tabs, you can simply use the cursor keys to jump between alignments. With spaces, you either use the ctrl+ combo or w and b if your a VI[M] user.

    With space, you’re keystroke count is much higher to enter _and_ delete indentations.

    Reply
    1. pmjones Post author

      @Richard Ayotte: I have not heard that particular argument before; thanks for mentioning it. As with the “deleting” argument above, perhaps I have been spoiled by the current crop text editors. Navigating across 4-space “tabs” in something like TextMate (or a properly-configured Vim) skips all 4 spaces at a time.

      Reply
  11. Rasmus Schultz

    I used to swear by tabs, but I was forced in use spaces in my current job – I could never go back! I’ve often thought about writing this article myself, but figured nobody would really care.

    Another point, I’ve come to realize, is if you IDE doesn’t handle spaces well, it’s not doing it’s job. Indent and outdent (automatic and manually, also for blocks) should be something that just works in any editor – if it doesn’t, you’re using the wrong editor! ;-)

    Reply
  12. ellisgl

    @Sean In NotePad++ I have a plugin that can align code by =’s and .=’s

    Reply
  13. Wil Moore III

    Not that it matters much, but I’d also echo the sentiment that 2-space folks aren’t as rare as one might think, but I’ve found that my taste for 2-space indent isn’t as appreciated as much in PHP-land as it is in Ruby-land, so I tend to not use it, though it is what I’d prefer given the choice. I just prefer consistency more so I opt to not go there in most cases.

    Reply
  14. Chris Bandy

    I’m reminded of Torvalds’ take on indentation: “If you need more than 3 levels of indentation, you’re screwed anyway, and should fix your program.”

    Reply
  15. Jaroslav Hanslík

    Inter-Line alignment is something like underscores for privates methods and properties. You just realize later that it’s better not to use it because of refactoring.

    Reply
    1. pmjones Post author

      That’s an interesting argument, one I’ve not heard before. Can you link to example stories, or blog an experience of your own, related to that (i.e., “inter-line alignment makes refactoring difficult”) ?

      Reply
  16. Jaroslav Hanslík

    Sean Coates mentioned the same problem in the first comment. He talked about adding new features but it’s the same problem with refactoring. If you just deside to rename a variable, one of array keys or function parameter, you have to realign.

    Reply
  17. Josh

    I do all of my work in Coda…the issue for me is that when I’m re-adjusting my indentation on multiple lines, I use their shortcuts ([command]+[shift]+”[" or "]“. The keyboard shortcut for that works in terms of tabs.

    I can’t imagine editing indentation en masse with spaces…you could see how quickly that’d drive someone to rage quit.

    Reply
  18. Patrick Allaert

    Hi!

    I will second what Sean Coates and Jaroslav Hanslík have said previously, if Inter-Line Alignment looks “nice” and can be considered as a good practice at first, they might become a true nightmare on the long run and tend to forbid them when I am involved in defining coding standards for new or existing projects.

    I will try to illustrate why with an example, quite extreme, I agree.

    Let’s have a file containing some data definition:
    Using alignment: https://gist.github.com/2313260/154aae585265f1bffb6541e0354a45e5cf0e39eb
    Not using alignment: https://gist.github.com/2313269/11c1e4efd773dca90ab56164a58d4845273828ac

    Because of refactoring needs, we want to change the keys from using underscores to camelCase which means we want to change:
    “operation_types” to “operationTypes”
    “call_method” to “callMethod”
    “parameter_type” to “parameterType”

    This can be done using tools like sed:

    sed -i 's/operation_types/operationTypes/;s/call_method/callMethod/;s/parameter_type/parameterType/' function_definition.php

    like codemod by Facebook
    or with simple text editors with search/replace

    In the example using alignment, I have to additionally rework the alignment either manually (about some minutes) or through IDE plugins (which might not exist everywhere).

    The results after the change can be found at:
    Using alignment: https://gist.github.com/2313260
    Not using alignment: https://gist.github.com/2313269

    In the aligned case, it generates a diff like: https://gist.github.com/2313332
    While in the unaligned case: https://gist.github.com/2313342

    Having much fewer lines modified has several advantages besides that you will avoid the time spent on changing the alignment:
    * You have diff/patch which are much nicer to review.
    * You will minimize the chance to have conflicts, whether it’s with other patches created before that kind of changes to happen or with others that already have local and uncommitted changes.
    * Blaming files with your VCS, you have the chance to discover the initial of a line much more directly.

    The example used is using alignment in array definition, but you have the exact same side effects with aligned variables definitions.

    As a general rule of thumb, my suggestion is to: Never align on something which depends on a size that could vary over the time.

    Just my 2 cents.

    Cheers,
    Patrick

    Reply
  19. pmjones Post author

    First, I would argue that the initial alignment style is ill-advised. Take for example this set of aligned assignments using underscores:

    https://gist.github.com/2313989

    It is identical to the initial unaligned version, with alignment added along the => operators. Refactoring of that to camelCase would produce a similarly small diff. One *might* have to manually realign on the changed lines, but the regex could (in theory) be extended to add one space in the right place to compensate for the missing underscore.

    Second, “hard cases make bad law.” A refactoring of that sort is likely to bring up other issues as well that will need to be addressed manually. I assert that alignment for readability is well worth the effort when you are already committed to changing large blocks of code at once.

    Reply
  20. Patrick Allaert

    Can’t agree more with you about the ill-advised initial alignment, but please, don’t say it is “mine”, it’s simply not! Just a real life case ;)

    You can create a regular expression to fix this for the usual case (changes on same line), but if you need to touch the other lines, a multiline regex change seems really complicated or even impossible.

    The most important thing is that if you have a change that introduces a misalignment and that you are going to fix that in the same commit you are definitely breaking the principle of atomic commits!
    To quote http://en.wikipedia.org/wiki/Atomic_commit#Atomic_Commit_Convention on that subject: “The greater understandability comes from the small size and focused nature of the commit. It is much easier to understand what is changed and reasoning behind the changes if you are only looking for one kind of change. This becomes especially important when making format changes to the source code. If format and functional changes are combined it becomes very difficult to identify useful changes. ”

    In practice this becomes very hard to visualize, see https://github.com/ezsystems/ezp-next/commit/dc44a52e7a050705c1c3ec288605fcd4a6a95b53#L1L2525 as an example.

    If you are not lazy and are very well disciplined to commit this in separate commits, it will still break the *blame* feature of your VCS, a very bad thing from my experience.

    > A refactoring of that sort is likely to bring up other issues as well that will need to be addressed manually.

    Not necessarily, hence why I talked about codemod.
    I also very frequently modify files using sed.

    > I assert that alignment for readability is well worth the effort when you are already committed to changing large blocks of code at once.

    Sorry, but did I read this correctly: “Committed to changing large blocks of code at once”? That is the worst practice you can ever have when using a VCS.

    I’ve quickly setup a github repo to demonstrate how bad this practice is:
    http://patrickallaert.github.com/avoid-variable-declaration-alignments/

    Don’t take me wrong, I have put myself that kind of alignments enforcement in my earlier coding standards but I have learned from this experience that this has much more drawbacks than advantages.

    Reply
  21. pmjones Post author

    Re: the code not being “yours,” I stand corrected. I have edited the comment to say “the” and thus place blame elsewhere. ;-)

    You didn’t *quite* read it correctly. I said, “when you are *already* committed to changing large blocks of code.” Or, if you like, “making wide ranging changes.”

    If “the principle of atomic commits” is the only thing going wrong here, then I think your problems are few indeed. ;-)

    I, and others, have been doing alignment of this kind for years, and have found it improves *readability* dramatically. I agree it introduces a *maintenance* cost, but then, none of the good things in life are free. The advantages of readability outweigh the maintenance costs, in my experience, but of course YMMV.

    Reply
  22. Ninj

    Hi,

    As often on the web this article is just a well-constructed piece of personal argumentations which its subjectivity makes hard to read when you decide to analyse each affirmation.

    What is wrong with all the people around thinking that saving up 15% bytes (even 30% when considering the uncommented version!) is useless? How can you try to convince people by writing “uncommenting gives better result than tabbing so, though it can be used together, i prefer to use only uncommenting”. It’s like “i can earn 2000$/m monitoring a security screen and 1000$/m testing earphones, which can be done together, so testing earphones shouldn’t be done”. That’s simply _not_ an argument.

    Then, you are taking for true the fact that line length limitation is not to be discussed, then write that tabs make longer lines. Please, read again the real arguments for line length limitations: limit the maximum words a brain can read on a line before to forget the beginning. Just read the article you linked in your own post. Put as many tabs as you want before the first word, word count will _not_ change. I’m not even discussing the linked article, which seems only partially true to me because reading a book and reading code is not the same exercice, but whatever. So tabs making long line is perfectly ok for readability, each developer choosing his preferred length for tabs. Here again, your argument is just not an argument. At all.

    The last part is the one i understood the less: inter-line alignement. You state a problem and its solution (tabs for ident, space for align) then say “but what if a developer would break all the rules and do a mess in your nice code?”. What? I mean if a developer does mess in code, he will always do it, no matter what _you_ wrote. How can “others are evil” be an argument for “don’t use that rule”?
    Citation: “That looks OK, right? Sure … until a developer, through habit (and we are creatures of habit) hits the tab key for alignment when he should have used spaces. They are both invisible, so the developer won’t notice on his own terminal — it will only be noticed by developers with other tab stop preferences.”
    Make spaces visible, and protect yourself against stupid developers. That’s it. The stupid developer is the problem, not you choice about spaces and tabs. I can’t see any argument in this part, honestly, but tell me if i misred something.

    Finally, spaces have drawbacks which you list but don’t really stop by. You should, because they matter.

    No offense, i hope you don’t think i’m angry, i’m not :) Just i’m against the texts that pretend to analyse a problem while in fact they are writen by a already fully convinced author, thus not really adding to the debate.

    My personal experience shows that tabs for identation are going very well together with spaces for alignement, i never had any problem in 12 years of coding, except with some bad IDEs.

    Thank you for reading ;)

    Reply
  23. Omega_

    This explanation only presents one preference which is to have text line up over multiple lines. To which I say: This is not word processing and you’re not making pretty pictures.

    And while legibility is a priority, this takes it to an extreme. The benefits of tabs far outweigh simply making sure you can draw straight vertical lines with your code.

    Another good “minor” (they’re all minor really) reason for tabs: Cursor travel. When navigating with a keyboard, you can cruise through tabs. They’re also totally unused as whitespace in a string, so can be treated as a “whiterspace than space” character.

    Another one? Wasted keystrokes spending all that time making pretty pictures.

    So basically in the end: If you’re creating some kind of new scope on the next line, hit tab. Otherwise, don’t. And if you’re ending it, go back a tab. Having something match up with an equal sign is just pointless.

    Maybe try a new line instead or something.

    Reply
  24. Keith

    Sean Coates is right. As is Omega_. I will also point out a number of additional parts.

    1. The argument for lining up multiple lines being easier with spaces is flawed. You can fix all your examples above where changing tab stop width adjusts display by using a tab character *after* the equals.

    2. Cursor navigation / travel is also a very real reason to prefer tabs over spaces.

    3. The line length argument is flawed. Mainly because it doesn’t matter whether line lengths exceed a “recommended max” by 7 characters (realistically the longest tab in common use). Max line length should be a guideline, not a rule, specifically because recommending a max line length is designed to improve readability most of the time, not to fit within a certain set of limits.

    4. There’s another significant downside to spaces (and upside to tabs, most of the time) – the space character is small, and it’s easy to make single-space alignment errors.

    The number of projects I’ve worked on that have single space alignment errors (i.e. 3 spaces instead of 4 in some places) is absurdly high.

    Tabs are (almost) always set to at least 2 characters, so it’s much easier to see stray tabs in your code.

    So, to sum up – the reasons you mention to use spaces:
    1. Comments are useful, visible elements. It’s irrelevant to compare removing them to removing 3 characters per indent. Using tabs is *free* compression. If you scale this out to billions of lines of code using tabs, that’s a lot of energy we’re wasting moving this crap around.

    2. Line-length recognition only matters if your coding standards are stupid – i.e. they *enforce* a max line length. Good coding standards *recommend* a max line length. Someone with a large tab width setting is obviously prepared to see things wider, so point is irrelevant.

    3. Inter-line alignment with tabs can be solved in almost all cases *by using an extra tab*. Sure, it might not look as “pretty” sometimes, but get over it. If you’re using spaces to make code “pretty”, you’re doing it wrong.

    tl;dr: All your arguments for using spaces over tabs are flawed.

    Reply
  25. Thomas Higginbotham

    I agree with Keith regarding line limits being more of a guideline than a strict rule. That leaves the alignment argument, and I think that Ninj covered that one well. Early in your article, you ask if there are reasons for preferring tabs other than the two you mentioned (saving space and configurable indentation). A couple reasons that I haven’t seen mentioned already are that they require fewer key strokes in simple text editors (yes, sometimes you’re forced to work in someone else’s environment without a nice editor), and tabs are better for readability (a single space can be easily overlooked, but it’s much harder to not notice a tab).

    You also didn’t seem to address any of the problems with spaces. I know you wrote this article quite some time ago, so I’m curious to know if your views have changed. Here’s my own take on the debate: http://goo.gl/UHoVp

    Regardless of what style you prefer, unless you’re starting a new project, it’s always best to continue the style from the previous developers. Either tabs or spaces is a better choice than mixing them up or wasting everyone’s time by converting their code.

    Reply
  26. Dave

    The only good argument here is the line-length argument, and that’s kind of a moot point because it’s easy enough for people to decide on a space-length for tabs or line length. Spaces for indentation just seems like a lot of extra work unless your code editor can automatically format it for you on the fly.

    The inter-line alignment argument is terrible, as you may need to add a variable that has a longer length than the other variables, meaning you have to change all the alignments on the other lines or format your variables to fit the longest one. This is terrible for version history or naming conventions and can take a lot of time.

    Reply
  27. Aeomer

    When using tabs or spaces, the correct spacing for indenting should always be a prime number less than ten for readability.
    Oh, I can hear the fevered scratching of heads :-)
    Yes, my C and C++ code of yore used tabs at 2, 3, 5, or 7 spaces. This works because most language primitives are a prime number of characters in length. Mathematically, it beautiful.

    Reply
  28. Renaud Lideln

    Not sure if I’m stating in my answer something other people already stated.
    But as a pro-tabs, arguing about it with so many developers, I had to comment this article that a pro-spaces friend sent me.

    Regarding your question “If there are other reasons I have missed, please let me know.”, I will kindly let your know (I may be missing some other advantages):
    – Tabs allow for fewer (and easier to spot) indentation mistakes (think about 3 or 5 spaces instead of 4)
    – SHIFT+TAB for decrementing indentation made of spaces does not work in every editor around there (for example, Aptana 2 does not handle it by default, you would have to add a plugin for that I suppose)
    – It may seem minor, but positionning the text cursor with the mouse at the beginning of the line is really annoying when indentation is made of spaces! Pro-spaces would reply: “use home”. No kidding. But why bother when it is so much easier with tabs?

    Also I would like to insist on the fact that suggesting to remove comments on PHP source code is a crime against humanity (unless I misunderstood your suggestion).
    Also, using tabs in HTML/CSS/JS files actually reduces file size (even though I agree that minification and gzip compression best practices tend to nullify this reason).
    I will shorten this in: storage is not important, bandwidth is.

    The argument about the line-length may matter to some people, but unless there is a (kindof prehistorical) technical limitation behind that, I consider it a vestige from the past back when terminals where 80 (or whatever) characters wide. Yes, some will say that for collaborative projects it may be important to define some rules to keep the code clean, but it is also a matter of basic logic not to have a 300 characters long line, and, please be honest, a possible difference of 3 characters (1 tab vs 4 spaces) won’t make the line unreadable.

    The argument about the inter-line alignment may matter to some people, but I personally consider inter-line alignment as a bad practice, because of the near-to-null advantage it brings, and because of the problems it generates when modifying variable names (no matter you are using spaces of tabs, it will kill alignment either way).

    Having killed (in my opinion at least) your only two counter-arguments against using tabs, I therefore consider that tabs offer many advantages, whereas spaces only bring handicaps.

    And for people stating YAML files, I could reply: this is a grammar rule to use spaces, and it has been decided so because of historical reasons regarding the tabulation character replacement with random spaces characters on each developer IDE that would, indeed, break indentation (because the parser would then not be able to guess the depth of each line). But then again, using tabulations as the only acceptable character for indentation in YAML files would fix everything, AND would allow developers to use whatever indentation width they prefer in their IDE without changing the file.

    Best regards,

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *