As a developer, our goal is to write high quality code. Before going any further, let’s define what high quality code is. Obviously it has to work as expected and is free of bugs, but the answer goes further than that. High quality code is easy to understand, modify, and debug. Overall, it is easy to maintain.
When we learn a new language, we usually begin to code in a specific style that we develop on our own. Once we start to code using a particular style, it becomes like a spoken dialect, and we may use it everywhere we can. The style you choose comes down to personal preference and what you find easiest to code and read. It might include conventions on how you name variables and functions or how you comment on code.
A big part of code maintenance involves reading and understanding the code. In an organization like Jet, we have a large volume of code, and many developers are working on the same code base. The code that one developer wrote will be read by other developers who need to understand and/or modify it.
There’s nothing worse than inheriting an application or needing to make changes to code that requires a lot of energy to decipher. You end up trawling through lines and lines of code that don’t make the purpose or intentions clear. Looking through unfamiliar code is much easier if it is laid out well and everything is neatly commented with details that explain complicated constructs and the reasoning behind them. It is estimated that developers can spend up to 70% of their time just looking at source code. So, conflicts in coding style will be a huge drain on the team’s productivity.
The Solution: Coding Standards
A coding standards document tells developers how they must write their code. Instead of each developer coding in his or her preferred style, developers will write all code to the standards outlined in the document. This ensures that a large project is coded in a consistent style — parts are not written differently by different programmers. Not only does this solution make the code easier to understand but it also ensures that any developer who looks at the code will know what to expect throughout the entire application. Let’s take an example of a code below.
Looking at this code, one might get confused as to why the variable “Woof” started with a capital letter (a.k.a PascalCase) while the rest of the variables all seem to begin with a lower case letter (a.k.a. camelCase). This might further confuse the reader of the code to believe that the variable “Woof” has some special significance when it fact it is just another variable. If the same code is written as shown below, it will eliminate any such confusion.
We keep mentioning “readability”, but what actually constitutes “readable code”? As we said at the beginning of this discussion, you want to create maintainable code. If you stop developing a project, return to it several months later, or hand development over to someone else, you (and other developers) want to be able to understand what’s going on in the code.
How Did We Define Our Coding Standards?
Coding standards are great, but how do you decide which standards you want to apply and how they will be defined? We use F# as our primary development language, and unfortunately, since there is no industry coding standard that we can yet use, we had to come up with our own. While crafting our coding standards, we looked into the following points:
- Any style should ensure that we can read our code easily.
- Can you actually read the code? Is it spaced out clearly?
- Do you separate blocks of code into “paragraphs” so that different sections are easily defined?
- Are you using indentation to show where control structures (if, else, while and other loops) begin and end and where the code within them is?
- Are your variable naming conventions consistent throughout the code, and do they briefly describe that data that they’ll contain?
- Are functions named in accordance with what they do?
- If you come back to the code in a few weeks or months, will you be able to work out what’s happening without needing to look at every line?
- How are you commenting the work?
- Have you used complex language functions/constructs that are quicker to write but affect readability?
Once we considered those points, we began to draft coding standards in consultation with our team members. The goal was not to force total change upon everyone but to compromise and incorporate elements of everyone’s style. If someone has been coding in a specific way for a long time, it will take a while to change to the new method. Developers will likely adopt the style gradually, just as an accent develops over time. There were conflicts, and while we cannot resolve 100% of the conflicts, we tried to keep them to minimum. Finally, we drafted out coding standards and circulated the document within our team.
Incorporating the Coding Standards in Our Processes
Having a standard in place is by no means an end. It has to be incorporated into the development process of an organization. A typical development process at Jet (and in other organizations) would involve individual writing code on development machines using an IDE or some form of editor with command line compilation tools. The code is ultimately checked into a SCM, from which it gets picked up by the build pipeline. At Jet most of the engineers use Visual Studio as the IDE of choice for F#.
We have been working on plugins for Visual Studio that can highlight all coding standard violations as the code is being written. This has the benefit of providing immediate feedback to the developer. Moreover, we are in process of integrating it as part of build pipeline. When the code is picked up by the build pipeline, it would be passed through a scanner that would scan the code for violations. At that point, if there are violations, the change would be blocked.
Technical Debt and Remedies to Fix It!
If an organization needs to adopt new coding standards, one would wonder what would happen to all the code that was written prior. We wrote so much code before we had the standards. As a result, a lot of code we have does not follow our standards, and this has resulted in the accumulation of technical debt. We have plans to develop code formatting tools that can convert the code base by parsing the current code, formatting it according to the new standards, and outputting the newly formatted code. It turns out that there are standards tools available that can do the job of converting source code pretty well. Alternatively, developing an in-house tool is also not a very big challenge since creating a parser/pretty printer is not a big challenge.
As this code base is already in use, we need to be careful since there is the potential to break the code. If the conversion process is not 100% correct, we might end up introducing bugs in already working code. Thus, we plan to proceed very slowly in clearing out technical debt.