3 ms·
One of the main drivers for spaces is alignment, which you should never attempt to do with tabs (except in contexts which normalize tabstops, which generally ex
by scrollaway 10y ago
One of the main drivers for spaces is alignment, which you should never attempt to do with tabs (except in contexts which normalize tabstops, which generally excludes programming).
Aligning within a line can and should be done with spaces. There's good reasons against alignment in such cases -- for example, it creates git blame/git diff noise when reformatting due to having to update alignment on a bunch of other lines just because you introduced a variable one character longer than the others. Irrelevant, though; such alignment is perfectly fine to do with spaces in a context where you indent with tabs.
The other type of alignment is beginning-of-line alignment, which is indeed not doable with spaces. Some people recommend doing such alignment with spaces despite the tab indent (cf. http://dmitryfrank.com/articles/indent_with_tabs_align_with_spaces http://dmitryfrank.com/articles/indent_with_tabs_align_with_...). It's a valid argument but I feel it's too much of an aberration to be taken seriously.
I personally find such alignment generally repulsive anyway. Take a look at the following code and tell me which method looks better:
http://sprunge.us/ZFHJ http://sprunge.us/ZFHJ
Too many times have I seen such function calls where the space between the parenthese and the soft wrap leaves <10 characters to work with. And here we go with one small argument per line, every argument preceded by 70+ spaces. I know programmers who could fit video games in the bytes used for just a single function call like that.
- Stratoscope 10y agoIndeed, column alignment is just about the only reason to prefer spaces for indentation. If you use column alignment, then indenting with spaces avoids the question of "tabs for indentation, spaces for alignment." But I'm with you: that kind of column alignment is harmful to maintainability, and I find it much less readable too. Some time ago I posted a few examples of column alignment gone bad, from the Servo source code: https://news.ycombinator.com/item?id=9469713 https://news.ycombinator.com/item?id=9469713 and also discussed alignment here: https://news.ycombinator.com/item?id=9469713 https://news.ycombinator.com/item?id=9469713 Once you give up column alignment, there's no longer any real reason to prefer spaces, and you can gain the benefits of using tabs. As a side benefit, when you give up alignment, your code becomes just as readable in a proportional font as a monospaced font. More details in my previous comments linked above, so I won't rehash them here. :-)
- scrollaway 10y agoHah, those are beautiful examples, thank you! :) The latest I encountered was a few days ago in the allauth codebase, where I found several instances of things like these: https://github.com/pennersr/django-allauth/blob/07d70fd68c4cb87b8eb4770952a029d8c72db392/allauth/account/views.py#L621-L624 https://github.com/pennersr/django-allauth/blob/07d70fd68c4c... I remember that page, actually. It's a really good point that code alignment breaks proportional fonts, I never considered it. More points for accessibility I suppose!
- jbpetersen 10y agoHow I wish for a universal standard of two tabs producing automatic alignment with whatever also follows a corresponding two tabs on adjacent lines.
- piaste 10y agofor example, it creates git blame/git diff noise when reformatting due to having to update alignment on a bunch of other lines just because you introduced a variable one character longer than the others. If you're working with git on a non-whitespace-sensitive language, and this annoys you, you can use the --ignore-space-change option to avoid this.
- Stratoscope 10y agoThat is certainly true! But the problem is I don't want to ignore whitespace changes when I review my diffs. If I do that, I'm very likely to introduce inadvertent whitespace changes that will annoy everyone I work with. :-)
- chriswarbo 10y ago> Take a look at the following code and tell me which method looks better: That seems like a strawman to me. I would go with something like: function() { nested_code() { some_very_long_function_call( long_argument_one, long_argument_two, long_argument_three, long_argument_four, ); } }
- scrollaway 10y agoThat is no semantically no different to #2 so I'm not sure why you think it's a strawman seeing as you just agreed with me. While, like I said, there's reasons against alignment within lines, using tabs doesn't prevent you from doing it.
- chriswarbo 10y agoI meant that aligning columns is orthogonal to breaking up long lines; you can do either, both, or neither, so your example comes across as a strawman.
- scrollaway 10y agoThis isn't about breaking up long lines. The second indent style results in shorter lines, that is one of the various side effects which makes it superior. My example was meant to display that start-of-line alignment is generally a poor idea and there are better alternatives... which you seem to understand just fine.
- Stratoscope 10y agoBy definition, scrollaway's example is not a strawman, because the first version matches the way I've seen code formatted very many times. (I wonder if this why your comment got downvoted? FWIW, I upvoted you for engaging in the discussion.) Personally, I would do his second example like this: function() { nested_code() { some_very_long_function_call( long_argument_one, long_argument_two, long_argument_three, long_argument_four, ); } } In other words, once I get to the point of splitting up the call into multiple lines, I generally split all the arguments onto their own lines. Now all the arguments are lined up with each other, as they are in your example. This matches how I format multiline statement blocks: if I'm splitting the code to multiple lines, then I split it consistently on each argument. This way I don't have to worry about how many arguments fit on a single line. Of course I'm not entirely consistent about this. :-) Take a function like CreateFile() in the Windows API. It has so many parameters, and you're likely to pass in NULL or 0 for so many of them, that it makes sense to bunch them up a bit to not use so many lines. But even then I wouldn't start adding extra spaces within a line to make vertical columns out of it.
- betenoire 10y agomy opinion: The second is better looking. I'd rather maintain the second. But... The first is easier to read. The shape of the code is enough for me to parse without effort. In the second, I have to "walk myself" through the code, even for this little example. I feel the effort required as soon as I have to start looking for the embedded commas. So I usually choose something like the first, since time spent typing matters less than time spent thinking.