Coding Standards: Humans Are Not Computers
This is part rant and part poking fun, but I’ve grown weary with the sight of source code running through phpcs for PSR-2 compliance and finding that it’s riddled with dozens and dozens (and dozens of dozens) of errors and an apparently infinite number of warnings. If I actually fixed all the reported problems, I’d drive myself crazy. I’m not crazy. I’ve avoided insanity because I quit using a coding standard. It’s too much and I freely admit it: I loathe coding standards.
Or do I?
The problem with coding standards is not the notion of following conventions to ensure all programmer can quickly read and understand code (and other good stuff), but that someone created a tool to actually check compliance: PHP_CodeSniffer. This isn’t a complaint about the operation of phpcs, but to complain about the mere fact of its existence. Automated tools catch everything. Every minor deviation, every judgement call about what looks neat, tidy or pretty, and every crucial space character found out of place is tallied into a wall of text in your console demanding that all these crucial lapses are fixed post haste. It doesn’t even have the decency to use smilie faces.
Using the cover of such automated tools, we can make judgement calls about code quality, integrate style checks into Continuous Integration scoring schemes, complain about pull requests and patches, and generally impose a time penalty on writing code. There is a point at which common sense morphs into sheer nitpicking, and an automated tool is the perfect nitpicker.
Get Outta My Way!
For me, a coding standard must have flexibility and it must remain invisible 99% of the time. If the damn thing makes sense, a programmer should have it learned inside of a week. If they have it learned then why would they need constant monitoring? Rather than catering to everyone by dictating everything (and then failing to do even that!), a coding standard should instead state a subset of common sense rules that everyone already uses. In otherwords, it should be almost utterly pointless to an experienced programmer. There’s already a good example of this. PHP-FIG has PSR-1. It’s basic, adheres to standard practice, and you’d have to be doing something completely weird to fail compliance. In other words, it’s perfect.
Beyond PSR-1, we then have PSR-2. Plug PSR-2 into PHP_CodeSniffer and a gateway to Hell will spawn. Most of the standard itself is actually quite logical. In fact, most of it is! The problem is when PSR-2 descends into seemingly trivial matters or omits specific use cases, and then implicitly demands total unquestioning obedience. The trivial matters are those that just never occur to me as being problematic (yes, that would be “opinion”) or which my editor does by default. The omissions are cases where PHP_CodeSniffer feels the need to fill in the blanks, or worse, where an interpretation of the existing wording is in doubt. Both fill my screen and CI reports with utter junk (which is more opinion).
Am I expected to waste my time fixing this junk? I don’t think so. I have better things to do like writing more code, more tests, more documentation, and more rants about the state of security in PHPland. Perhaps eating and sleeping in between ;).
PSR-2 !== PSR-2
What has happened to PSR-2 is that it was made a standard rather than a living document, and it has not achieved the full benefits of either option. There’s as many PSR-2s as there are PHP programmers. Every individual has scope to re-judge the ambiguous bits, re-define words, and fill in the blanks as they see fit, whether that individual be you, me or the authors of coding standard tools. As a standard, it doesn’t quite sail smoothly. Even with the recently introduced notion of using errata, it still leaks like a sieve. It’s like having a living document by the back door but it also relies on retroactive reinterpretation of the existing text without actually changing the text per se. It’s working slowly but it’s also a thankless task for whoever is spending time on it.
I could spend time retraining old habits, reconfiguring editors, using pre-commit hooks to get phpcs reports, but that goes against the idea of limiting waste time and absorbing the occasional mistake if harmless. I simply do not want to spend time worrying about this unless I’ve done something obviously unforgiveable. All those minutes add up and they have a cost measurable in productivity and sanity. Another example of this silliness is the quest for perfect test coverage of source code. It’s another time sink exercise to resolve some imagined evil. A test suite with 100% code coverage can either have a perfect test suite or an unconciously manipulated test suite that doesn’t test all possible logic branches but manages the same score. Programmers will cheat the system when you push them too far. Those with the least experience will cheat the most, and I don’t blame them – experience doesn’t come overnight simply by setting out strict rules and arbitrary penalties. Automated tools can’t tell the difference. They are stupid animals.
The Perfect Coding Standard…
A perfect coding standard is, in my opinion, one which limits the rules, eradicates ambiguity, formulates multiple use cases and avoids trivialities. It’s ruleset count would be more than PSR-1 and less than PSR-2, but with greater focus, explanation and examples. For example, if I place a newline before the closing curly bracket of a class, will the planet instanstaneously implode? Probably not. Will a programmer notice it? If they do, I feel sorry for them. Does PHP_CodeSniffer currently torture me with it? YES. MAKE IT STOP. If I use a shorthand control statement, will the planet instantaneously expl… You get the picture.
Some of these rules make sense if a file is overburdened with them to the point of being illegible, but most are once off misfires and laziness. Harmless. If a Human saw them, they should be able to use their brain. If PHP_CodeSniffer sees them, it makes a console mess. It does not compute.
So a perfect coding standard doesn’t simply eliminate trivialities, it defines a scoring system to save us from overeager automated tools. The occasional slipup won’t penalise you too much and it won’t give you 100%, but neither will it see you sent off to make one character changes for the rest of your mortal life as a precondition for earning the approval of a frickin’ computer.
It gets better! Since such a coding standard would eliminate trivialities, omissions and be more explicit about those it retains, the chances of actually violating it would be less. The probability of scoring really well would be really high. If that point can be reached, you have a coding standard that works with programmers, isn’t overly judgmental, and doesn’t flood your terminal with nonsense.
Well, I can dream… Humans are not computers to expect perfection from. It’s actually irritating when people do.