PHP PSR-12

It was a bit odd to me that a “Framework Interoperability Group” would recommend a coding style that is apart from functionality.

Problems With Coding Style Differences

I’ve seen a few reason why people excuse mandating a coding standard

  1. “to reduce cognitive friction when scanning code from different authors”
  2. coding style related commit diffs obscure actual code changes

The reality is, these two excuses hide the real issues. Let’s explore.

For issue #1, any code that adheres to some sane coding style has never caused me cognitive friction, even when there are mixed styles, so long as the indentation is the same. I’ve worked on many different code bases with different styles, and the only time there is an issue is when the coder has abandoned clarity (such as not maintaining proper indents). The real issue behind #1 is actually split into two issues:

  1. some programmers program without clarity
  2. some programmers encounter “cognitive friction” when seeing a coding standard apart from what they are used to

Requiring a specific coding standard gets rid of sub issues 1 and 2.

But, I’ve never met a sub-issue-2 programmer. Further, code without clarity is readily identifiable. Forcing a coding standard helps prevent a bad programmer from showing up through their unclear code.

For issue #2, this is again split into two issues

  1. formatting changes should be a different commit
  2. formatting changes should not be a commit for code that is already clear

Let’s say the !! was accidental, and someone with a different style edits the following code:

if(!!$is_active){
	#...
}

changes to

if ( !$is_active )
{
	#...
}

Even in this case, if this were a commit, it would still be clear what was changed.

What becomes a problem is when a programmer modifies code for style purposes only, and commits that with non-style related changes. It is a problem that pretty much would only occur with a bad programmer, who did something like, auto-style-format a file after making a change to the logic, and then committed the file. The absence of mind not to realize that the logic change will be buried in the style changes does indeed point to a bad programmer.

Normally, when a programmer x with style 1 edits code from someone else that is styled with style 2, two outcomes might occur:

  1. the sections of the code that programmer x modifies/adds become style 1
  2. programmer x uses style 2 for this code

Either of these cases is not a problem so long as both style 1 and style 2 are clear and the indentation is the same. Amusingly, with outcome #1, it makes it more immediately apparent there was a different programmer who worked on the code. But, even in the case of #1, back in 2006, when i was working with svn, I wrote an svn hook that took the code I submitted and formatted in accordance to the project coding standard. With such a hook or auto formatter, it wouldn’t matter if the outcome was #1, because the code that made it to the project would remain standard to one style.

But, if outcome #1 occurred with no hook, the issue with mixing styles is primarily an issue of indentation type. Given editors now will adapt the indentation type to the indentation type present in the file, this is normally not a problem.

Google has some insights on coding standards

  • The benefit of a style rule must be large enough to justify asking all of our engineers to remember it.
  • When something surprising or unusual is happening in a snippet of code (for example, transfer of pointer ownership), leaving textual hints for the reader at the point of use is valuable
  • "Just pick one and stop worrying about it"; the potential value of allowing flexibility on these points is outweighed by the cost of having people argue over them.
  • Consistency should not generally be used as a justification to do things in an old style without considering the benefits of the new style, or the tendency of the code base to converge on newer styles over time
  • The basic principle is: The more code that fits on one screen, the easier it is to follow and understand the control flow of the program. Use white space purposefully to provide separation in that flow.

Line Conservation

This last item from google is something that used to matter to me with smaller screens. When you have functions defined like

function bob ()
{
	#...
}

That extra line for the opening brace takes up space and accumulates across multiple functions, reducing the total amount of code on the screen. I tried to find why people prefer this style, and I get:

  1. easy to visually spot the beginning of the code block
  2. the presence of the function/method is clearer

Both of these justifications are trivial. For #1, that is what indentation is for. For #2, get an editor that better highlights method/function definitions so they are clearer.

In reality, my impression is that some programmers get intimidated by dense code, and the extra newline for braces helps to reduce the intimidation.

When screens were smaller, and I couldn’t rotate my screen 90 degrees to allow even more lines of code, extra newlines meant my capacity to see a large number of useful programming lines was reduced. When you are getting the sense of a large class, the ability to rapidly scan it, scan through the methods, with the ability to arbitrarily drill in visually, is important.

To magnify this issue, imagine having an editor that was only 5 lines tall, and think of how long it might take to understand a large class with thousands of lines.

But, as screens are large and rotatable now, the extra line isn’t as much of a problem.

Spaces And Camel Casing

As a FIG PSR, I disagree with both the mandating of spaces and camel casing.

For spaces, since there are good reasons for both tabs and spaces, and the use of either doesn’t matter so much as does the consistency within the specific code of a project (doesn’t so much matter what libraries/plugins/extensions use), the mandating of spacing is an overreach.

As for the camel casing, as I allude to, camel casing variables and methods is a rookie mistake that I myself made for over a decade. The good thing, however, is that this aspect of the PSR can be ignored with almost no consequence.

When programmers are using a class, their expectation for the function names comes from first seeing the class functions. If those class functions are uniformly either camel cased or underscored, it sets their expectation for that class. So, to the degree that a function can be expected without looking at the actual function, a divergence from the PSR does not matter so long as it is consistent within the class.

There is a rare occasion that function names are dynamically determined by compilation of words. Despite writing such a compilation tool myself, this occurrence is so rare that it needn’t be considered.

It is just as unnecessary to conform variable names either way.

In Conclusion

  • PSR-12 will improve accessibility of code in projects that would have otherwise not had a coding standard.
  • The standard of spaces makes sense for most big projects, but does not make sense as a standard for all projects.  There is nuance to the tabs vs spaces debate
  • The standard of camelCasing is good particularly in frameworks and common tools, but it is a bad standard for apps.  I explain this situation here https://github.com/CLR-MO/standard-coding#camelcase-vs-underscore and here https://github.com/CLR-MO/standard-coding#naming-exceptions
  • The placement of “{” on a new line for methods reduces the amount of useful code on the screen I can see at once.  Even google presents saving vertical screen space as an objective: https://google.github.io/styleguide/cppguide.html
  • Different styles don’t matter so long as they are clear. The mixing of styles is mostly a problem when tabs and spaces are mixed, which can be prevented by a good editor. Programmers have been modifying each others code for decades and different, clear, styles have not prevented interoperability
  • PSR 12 should not be a FIG PSR. The point of interoperability is whether some code will work in different environments. PSR 12 is for how programmers react to code, not for how the code functions in different environments.

Leave a Reply

Your email address will not be published.