A while back I tried to make the case to the author of Black (The python community's excellent auto-formatter) to add a "--use-tabs" option. I was not successful; I had to fork Black to be able to use it. https://github.com/jleclanche/tan
A while back I tried to make the case to the author of Black (The python community's excellent auto-formatter) to add a "--use-tabs" option. I was not successful; I had to fork Black to be able to use it. https://github.com/jleclanche/tan
I think this stems from a broken mental model, whereby tabs are regarded as "representing x number of spaces", where x is some unknown variable in the editor of whoever created the file. These people say things like "tabs are just a compression mechanism" and "tabs are inconsistent across editors". In the minds of these people, spaces have primacy, and tabs are just weird inconsistent not-spaces that catch you out.
The proper mental model, of course, is to recognize that tabs don't represent any number of spaces - they represent indents, and that's that. You could quite happily set your editor to display tabs as indents π spaces wide. It is an error on the part of the person writing the file to assume any particular tab width.
There are a few coding style conventions that break the assumption that the indentation should strictly reflect the nesting depth, like breaking up a long argument list over multiple lines and trying to line the second line up with the opening parentheses. In my view these are bad coding styles anyway and should be retired.
There was a viral joke tweet a while back suggesting that successive indents should be displayed with ever-increasing widths following the Fibonacci series. The result looked quite nice, actually!
int main(void){
indentedStatement()
}
However, the second is for aligning multi-line statements. Something like: int main(void){
foo(bar,
baz,
54
);
}
Here, the indenting on arguments baz and 54 really should be aligned with the argument bar. If we really want to combine both use-cases that involves a mix of tabs and spaces. Tabs fist for getting the number of nested scopes, with optionally spaces to align text.Meanwhile, mixing tabs and spaces is almost universally seen as bad. This makes sense because it is not visible where the tabs end and spaces start. This can easily lead to inconsistencies that are invisible to a writer, but are horrible for a reader with a different tab representation.
If you believe that indenting like this is a bad coding style, how do you suggest those statements should be formatted?
If you mess up, no big problem, someone else will see it and fix it. People screw up space-alignment all the time anyway.
Or, better still, don't visually align stuff. It's annoying as hell to maintain unless you use an IDE, and has a tendency to bunch stuff up toward the right margin when function names grow long. Just start the argument list indented by one tab stop on the next line. More visually consistent too.
foo(
bar,
baz,
54
);
Optionally the closing `);` could follow the last argument.The only exception is Lisp...because it's lisp.
tl;dr don't do that because it's ugly to conflate two purposes of indentation in this way, but if you absolutely must conflate them then do so explicitly with tabs and spaces, as you describe, and use an editor which makes the difference visually apparent.
This actually boils down to an argument in favor of tabs, because the additional semantic information allows the editor to present you more visual cues to work with.
int main(void){
[tab]foo(bar,
[tab][spaces]baz,
[tab][spaces]54
[tab]);
}Pressing tab in here doesn't give me an indent but changes focus.
But spaces always workHopefully you're not doing vast amounts of coding in a web browser text box anyway. If it's a more sophisticated web-based IDE, that keybinding can trivially be overridden in javascript.
I'm not religious about spaces and I 100% agree with the logic of tabs superiority because of its semantics of indentation. That said, I use often use the inferior spaces because it's the "least worst" option in a messy world where multiple programmers write inconsistent code with different tab settings of 2,4,8. (I wrote a similar previous comment.[1])
E.g. In C#, I could use Spock Vulcan logic and argue that tabs are superior but the reality is that the default setting in Visual Studio is that the tab key inserts 4 spaces. Therefore "tab consistency discipline" requires everybody change their settings, or constantly run code formatting tools (which is also not a default workflow), etc.
However, I notice that in collaboration on a MS Word document, it's easier to get everyone to maintain discipline with tabs because automatic numbered multilevel outlining does not work with variable spaces. Everybody editing the document notices the headings not getting renumbered which means the Table-of-Contents regeneration is also broken. This contrasts with programmers using various text editors with their inconsistent tab preferences of 2,4,8 leading to inconsistent code formatting and they don't realize that others see inconsistent formatting.
Because some programmers also use tabs for cosmetic alignment. (The other thread also illustrates some examples.) It doesn't matter if that's semantically incorrect. A lot of it has to do with muscle memory; the programmer's brain is on automatic pilot and therefore the left pinky finger just taps <tab><tab> ... to line up function parameters or the values of variables. This type of alignment is not always round-trip perfectly preserved with code formatting utilities that covert tabs->spaces->tabs.
(In other words, some programmers sometimes presses <tab> not for its semantic meaning but as a mechanical shortcut to quickly move the cursor to the right an arbitrary amount.)
One can make an airtight case for the rational purity of tabs but the problem is that the real world doesn't always want to cooperate.
I don't use VS so I'm not sure about this specific example, but from my experience, if you have to fight all your colleagues' editor defaults, you're going to have a hard time.
Black has the same philosophy as Prettier, which does provide a --use-tabs option. And the whole "hey, accessibility" thing kind of rings as "absolutely necessary" in my book.
I've had a bunch of people thank me for my fork because they wanted to use Black, but couldn't because they either preferred tabs or were required to use tabs. Similar reasons why Black provides a configurable max line length.
I mean, I've had this argument with the author, I don't exactly want to go over it again :) The official reasoning for not including tabs as an option is that "tabs for indentation are the devil". https://github.com/python/black/issues/47
Well, at least the author's honest about this being a religious argument, I guess