Recently, I had a conversation with a junior developer on my team. Let’s call him Alan. We were talking about a new notification feature that was going to be used to send reminder e-mails to potentially thousands of people if they had forgotten to enter certain data in the last month or so.
Alan was confident that the code he had written was correct. “I’ve tested it well,” he said. I had heard some variation of this statement from so many developers over the years that I sighed: “I’ve been writing code in a professional capacity for over two decades now, and yet even I don’t trust the code I’ve written.”
You can probably guess what happened to Alan’s “well-tested” code. In testing, a number of bugs were discovered, many of which were caused by incorrect assumptions on his part.
Now, I’m not picking on Alan. In fact, I hired him and the rest of the team for that matter. He may be short on experience and a little overconfident, but generally writes decent code, and constantly tries to improve himself, a trait that is more important than experience in my book.
As for me, I’m certainly not one of the best software developers in the world. I may not be a great one either. I’ve seen quite a few developers who have written qualitatively worse code than I have, and relatively few who have written better code. So, statistically speaking, I consider myself above average. How much above average, it’s hard to say, but it doesn’t really matter as long as one is aware of their limitations.
“The competent programmer is fully aware of the strictly limited size of his own skull; therefore he approaches the programming task in full humility, and among other things he avoids clever tricks like the plague.” – Edsger Dijkstra
Oh yes, clever tricks. It’s tempting to use them from time to time, but are you going to remember how you solved a problem when you revisit your code six months later? If you need to go through your code line by line just to understand what it’s doing, another developer reading it is unlikely to fare better.
It’s often said that writing code is easier than reading it, but that doesn’t have to be the case. When writing long sections of code, I find it helpful to stop every once in a while and review the code as if I were someone seeing it for the first time. I ask myself a few basic questions: Are my functions short? Do they have descriptive names? Is complex logic encapsulated within their own functions? Am I passing too many arguments? And so on.
Assuming that one writes reasonably easy-to-understand code, a major source of errors typically stems from the assumptions made by developers. Reality is messy. There are almost always edge cases that will bite you in the back.
Numerous “falsehoods programmers believe about X” pages on the web list commonly held but incorrect beliefs. For brevity, I will only include some I had the displeasure to deal with:
Falsehoods About Time:
- A timestamp represents the time that an event actually occurred.
- The time zone in which a program has to run will never change.
- Daylight saving time happens at the same time every year.
- Weeks start on Monday.
- Time always moves forwards.
- My software stack will handle it without me needing to do anything special.
[More]
Falsehoods About Text:
- ASCII data represents text.
- Interpreting common ASCII data such as tabs, carriage returns, and line-feeds is defined.
- A Unicode file that only contains ASCII letters, encoded in UTF-8, is a valid ASCII file.
- Latin-1 can be mapped directly into Unicode.
[More]
Falsehoods About Prices:
- Prices can’t have more precision than the smallest sub-unit of the currency.
- You can always use a dot (or a comma, etc.) as a decimal separator.
- Given two currencies, there is only one exchange rate between them at any given point in time.
[More]
Finally, for a curated list of a great many falsehoods, try this.
“Only the paranoid survive.” – Andy Grove
A piece of advice, if I may: Assume nothing. Don’t trust anything including your own code. List your assumptions. Double, triple-check every single one of them. If some of your assumptions are wrong, it doesn’t matter if your code is correct – it will inevitably fail. Challenge your assumptions, test them, and adjust as necessary. Trust me, you will sleep better at night.
Related: