Have you ever run into a new or trending programming language (Rust, nim, Kotlin, etc.), promoting all sorts of great "new" abstraction mechanisms (traits, mixins, multiple-inheritance, monads, lambdas, macros, you name it), thinking: "I could finally get rid of all this copy-pasted or boilerplate code we have in our codebase!"?
I discussed whether newer/trendier languages will lead to less copy-pasted code (or even better code quality in general) with a few colleagues over a few beers recently. Based on our experience as consultants for software quality and Teamscale developers, we quickly came to the conclusion: No, they will not.
Let me explain and give a few examples.
There are multiple reasons as to why this is usually not the case:
- Your current programming language is good enough
- Your programming language is not your problem, because
- Programmers are lazy
- The process sucks
I’ll go into more detail and give some examples in the following.
Your Current Programming Language is Good Enough
When we talk to clients and other programmers, we regularly hear them using their programming language as an excuse for poor code quality. "Well, you just can’t fix that in C#/C++/Java/Python/…". Most of the time, this is just plain wrong.
Java has inheritance, fairly powerful generics, static methods/classes, annotations and even lambdas. C# has all of that plus extension methods (which can be used to simulate mixins). C++ already had multiple inheritance decades ago and has a templating system powerful enough to implement Tetris in pure templates. In practice, we seldom see any copy-pasted or badly designed code that could not be improved using one of these features. In fact, most of the time, it all boils down to extracting methods or classes, simplifying code and using decent method or variable names, which can be done in practically any language.
Here is an example from the Jenkins source code (found on our public Teamscale Live Instance):
The image illustrates a small piece of copy-pasted Java code, that could have easily been refactored into a single method with one parameter (list of plugins). I would generally consider Jenkins to have a very high level of source code quality (e.g. only 1.7% clone coverage, whereas we often see systems with over 15% or even 25% in practice), and yet, even here we can find areas that can easily be improved.
While there certainly are examples of code that can not be refactored cleanly using language X and could be using language Y, switching the language will usually not fix the general problem. So unless you are using ancient languages like COBOL, your language is well enough equipped to battle most issues.
Your Programming Language is Not Your Problem
After having established that the language is not the problem, let`s focus on what is.
Programmers are Lazy
Like all people, we programmers are lazy (and often should be). Therefore, using copy-paste to generate "new" functionality is often accepted as necessary. Unfortunately, cloned code has a much higher probability of introducing errors to the code or making them hard to fix (check out my colleagues introduction to clones for more info).
Without the right tools, removing clones can be hard, laborious and error prone work. Fortunately, for most modern languages, we have powerful IDEs, that make extracting a method a matter of seconds and even help with introducing base classes. If you think refactoring takes too long, learn to use your tools: Eclipse, IntelliJ, Visual Studio with ReSharper. In my opinion, refactoring support is one of the most compelling reasons to use a widely used programming language with superb IDE support, over a simple text editor and a shiny "new" language, for larger projects.
Refactoring support in Eclipse:
The Process Sucks
All motivated programmers, IDE support and a great language is useless if your process/company/management forces you to churn out feature after feature after feature, without allowing you any time to refactor and clean-up your code. Unfortunately, this is very common among software development teams.
A good way to improve the situation is to make management aware of code quality and areas that need improvement. This can be done by using quality analysis tools such as Teamscale or with an objective external audit. By doing so, management is given the chance to allocate enough time for the team to improve the quality along the way.
We firmly believe that the most efficient way to achieve and keep a high level of code quality is to clean-up and refactor along the way and not in dedicated clean-up sessions. Clean-up sessions are highly inefficient, as the programmer needs to understand the code he wants to refactor almost as deeply as when working on a bug or feature, requiring a lot of time. It is much more efficient to fix quality related issues while working on a bug or feature, as the overhead of understanding the code has already been payed.
A Teamscale dashboard can help you keep an eye on code quality:
In conclusion, high levels of software quality can be achieved with most widely used programming languages. Personally, I think that great tool support is much more important than yet another abstraction mechanism.
Most importantly, software departments need to establish a culture around code quality and understand that is a vital part of any bigger software project, if that project is to be successfully developed for years to come.
What are your experiences? Leave a comment below!