TL;DR: You should write code in a way that your colleagues would understand best. After all, they are the ones that will be reading it over and over again. No matter in how much of a hurry you are, you should always take the time to give things meaningful names.
Who do you write code for? It’s a simple question with an obvious answer.
As Martin Fowler bluntly states it:
Any fool can write code that a computer can understand. Good programmers write code that humans can understand.
The days of a programmer writing cryptic assembly code that only their computer understands have long gone by. The question deserves attention however, as I seem to keep bumping into examples that prove not everyone shares this belief (or is too lazy to act upon it).
Recently, I came across a bit of SQL code that looked like this:
DECLARE @nvcWFN_SQL NVARCHAR(MAX) DECLARE @nvcWFN_SQL_1 NVARCHAR(MAX) DECLARE @nvcWFN_SQL_2 NVARCHAR(MAX) DECLARE @nvcWFN_SQL_2Bis NVARCHAR(MAX) DECLARE @nvcWFN_SQL_2Bis2 NVARCHAR(MAX) DECLARE @nvcWFN_SQL_2Bis3 NVARCHAR(MAX) DECLARE @nvcWFN_SQL_3 NVARCHAR(MAX) DECLARE @nvcWFN_SQL_4 NVARCHAR(MAX) DECLARE @nvcWFN_SQL_4Bis NVARCHAR(MAX) DECLARE @nvcWFN_SQL_4Bis2 NVARCHAR(MAX) DECLARE @nvcWFN_SQL_4Bis3 NVARCHAR(MAX) DECLARE @nvcWFN_SQL_5 NVARCHAR(MAX) DECLARE @nvcWFN_SQL_6 NVARCHAR(MAX) --The code goes on by initializing these variables with parts of --a SQL SELECT query SET @nvcWFN_SQL = @nvcWFN_SQL_1 + @nvcWFN_SQL_2 + @nvcWFN_SQL_2Bis + @nvcWFN_SQL_2Bis2 + @nvcWFN_SQL_2Bis3 + @nvcWFN_SQL_3 + @nvcWFN_SQL_4 + @nvcWFN_SQL_4Bis + @nvcWFN_SQL_4Bis2 + @nvcWFN_SQL_4Bis3 + @nvcWFN_SQL_5 + @nvcWFN_SQL_6 --Execute the dynamically generated query EXEC sp_executesql @nvcWFN_SQL
This is part of some code that generates a complex SQL query at runtime. Ignore the fact that this might not be the best idea ever, but just analyze the code itself.
I find it perfectly agreeable, even necessary, that the developer splits up the problem into smaller problems to make it more tractable. What I don’t like however is the naming of the variables. The only way to figure out what the variable named @nvcWFN_SQL_4Bis2 means is by looking up what value gets assigned to it. This is basically the same as saying:
Though luck, maintainer of my code. I expect you to plough through 1.400 lines of code to get a basic understanding of what it’s supposed to do.
I can understand the developer is proud of the script they worked very hard on. That does not mean I want to read each and every line every time I have to get in there to fix a bug. That bug could very well have crept in there just because of the poorly chosen names (This is definitely the case with untested code *cringe*).
The possible reasons
Why does cryptic code like this even exist? I can think of several so-called “legitimate reasons”, each of which I will try to refute.
Reason 1: I never thought about it
You might get this response from a fresh-out-of-college junior. I myself did not fully grasp the importance of self-explanatory code when I started my career in software development. It took me two years of experience and a lot of reading (you can view my reading list here) to finally get the message. Anyone more experienced should not use this as an excuse. Software development is a team sport, you should think about these things.
Reason 2: That’s how we do things here
I have actually had this reason come up in a discussion with one of my clients. What if the coding guidelines of your company offer very strict rules about how you name your variables? Martin from 8th color sums it up nicely:
Coding guidelines should be lines on the ground, not concrete walls.
Whenever you are in a situation where following the guidelines would do more harm than good, just ignore them. You could take this point even further: if cryptic names result in more bugs in your code, then guidelines that enforce them are causing more problems than they’re worth.
Reason 3: It’s the time pressure
We’re all on tight deadlines all of the time. That’s just a reality of software development. When the developer started writing the script that would become the 1.400 lines-of-code behemoth that it is now, I can somewhat understand they did not have a name for every variable they introduced on the spot. SQL is a low-level programming language that makes it harder to reuse code. There are little to no refactoring tools available in the SQL developer’s toolbox, so when you write something new you just start scripting away until you’ve achieved what you set out to do.
I strongly believe that you should never leave cryptic code as-is, just because of “time pressure”. This always blows up in someone’s face. Maybe it’s you a couple of days later, when the requirements have changed and you have to change the code. Or maybe it’s the poor sod that took your place and now has to implement a feature in the mess you left months ago. As we all know, developers spend a large amount of their time reading code others wrote. As a software professional, you have the obligation to deliver qualitative software. If management does not see it this way (“Why would you spend time on code that already works?”) and you cannot make them see why you need that extra day to work on it, it’s time to find a new employer. That’s just a recipe for disaster.
Reason 4: I cannot find a meaningful name
Now we’re getting somewhere! You’ve introduced a new concept and you’re putting in the effort of thinking about a name, but your mind just stays blank. Your conclusion is: “This concept is just too complex, I can’t find an elegant name for it”.
When you arrive at this point, we face a deeper problem. If a concept has a clear single responsibility, it should be possible to come up with a meaningful name for it. For example, you can name the variable that holds the WHERE clause of a SQL statement the “whereClause”. You can name a class that is responsible of parsing HTML an “HtmlParser”.
Conversely, when you find it difficult to name something, it might be the case that the thing just has multiple responsibilities. The solution to this problem is simple: split the concept up into parts that each have a single and well-defined responsibility and name each part after that responsibility. The resulting code will be more understandable and, as an added bonus, more reusable.
I’m not saying that finding good names for something is easy here. It may very well be one of the hardest parts of a developer’s job. Literally dozens of books have been written on the topic of “naming things”.
Now, I know the developer probably wasn’t trying to screw over their colleagues when they wrote the code from the example. They were just doing their job, had some working code at the end of the day, checked it in and never looked back.
I do know that if they had taken the time to reread their code from the perspective of its readers, i.e. their colleagues (and their future self), the names would have turned out to be much more meaningful. Writing stuff from the perspective of the reader is considered basic knowledge among writers, but it seems that sometimes developers forget that they are not writing code for the sole purpose of being interpreted by a machine.
In the example we only talked about variable names. Of course, this principle applies to every concept you dream up, be it a module, a class, a method, a variable or even the condition of an if-statement.
Next time when you are about to check in your code, take a moment to reread it from the perspective of someone that has never seen it. Is the code self-explanatory? Does it tell a coherent story that does not require criss-crossing through the code? Put in an effort to make your code as clear as possible. You will save your colleagues and your future self a lot of time and frustration.
- Much of this discussion traces back to what Robert Martin wrote in his Clean Code book. If you managed to make it this far in this post you should definitely check it out.
- A rather sarcastic article on how to “Ensure your job for life”, with nice examples of poor naming choices.
- Jacob Emerick’s beautiful phrasing of the solution: “Write your code as if you were telling a simple story to future developers.”