Saturday, March 16, 2019

I have converted at long last to 1TBS

After decades of firm adherence to the Allman brace style I have finally changed my mind. I am now in the 1TBS camp.
Here is my reasoning, it is all a matter of my own personal opinion of course. The stuff below is not trying to make a logical reasoned argument for 1TBS in general, just why I changed my mind.

IMO Allman is useful to show where code blocks begin and end in legacy code where functions ramble on and on as they grow uncontrolled and undisciplined over the years. Such source often contains a random mixture of tabs and spaces.
It is quite hard to see where the scope blocks are under these conditions. Reformatting Allman style makes such code clearer than it would otherwise be. Using an Allman style on new code allows it to grow in an uncontrolled way where blocks just get bigger and bigger, rather than being refactored. When this happens the use of Allman means the blocks that would otherwise start to become much harder to see stay reasonably visible.

So that's why I used to think Allman was good. It allowed blocks to be more easily seen in ancient crufty code and it allowed new code to become crufty while still preserving some ability to see the blocks. But I have now decided that this is not a good reason to prefer the Allman style.

We all know that advocates of 1TB say it makes the code shorter, and it does. And shorter code has become much more fashionable over recent decades. The shorter the code the smaller the blocks and once a block becomes only a few lines the Allman style makes such blocks unnecessarily longer. I see this in Java code where 1TBS is the dominant layout style and shorter functions are practised much more than in C++. Maybe it's because alot of C++ code is ancient and in the dim and distance past it was more normal to write long, rambling unfactored functions. Java hasn't been around long enough for such cruft to accumulate to the same degree. Plus it came along later during which time shorter functions became more fashionable. When was the last time you saw a Java function that rambled on for hundreds or even thousands of lines. I wouldn't be surprised if you've never seen one. But we've all seen it in C and C++.

So, if I ever get the luxury of working on a new C++ project and I get any say in things like layout style, I would advocate 1TBS. The project would have short functions and the minute a function looks like growing to the point where the blocks start to become less visible it would have to be refactored. This is not just a matter of making it look pretty. The argument for refactoring would be that the result would be easier to test and it would be easier to reason about code coverage, as well as being easier to understand. This is already standard practise in Java, thank goodness.
It ought to be standard practise in any programming language.

During my conversion to 1TBS I have been working with python. This is a language where the issue has been designed away. How jolly sensible. Why don't all new languages learn from this? Python seems to be the only one. Every time some new language comes out it is inevitably based in C++ regarding layout. Java copied this and so has almost every other language since.

There is another factor which led to my 1TBS conversion: I have been working on a project where Allman is the standard, but with a twist. Single statements must not be surrounded with braces. We all know how potentially dangerous that is. It can lead to the dangling else problem, and has done on that very project, a fact revealed by a clang-tidy analysis.
It can also cause a problem when a developer changes the code to make the block more than one statement. These issues just don't arise when one uses 1TBS.

So, how is this change in belief going to affect my programming life? Hardly at all, unless I write stuff on my own (e.g. updating my sourceforge projects or creating new ones). After all, I am in an environment in which
1TBS is forbidden and its use would probably harm the code base as it would make the blocks in long rambling functions even harder to understand than they already are. I can't even use 1TBS in the java code, since Allman is mandated there as well.