We’ve all done it: snagged a cookie when mom wasn’t looking, had a little too much wine for dinner, let the car sit in a parking spot after the meter expired.
We’ve even gone around Deadman’s Curve a bit too fast. And yes, we’ve all violated any number of the cardinal rules of programming, the ones that everyone agrees are bad. And we secretly liked it.
We’ve thumbed our nose at the rules of good programming, typed out code that is totally bad—and we’ve lived. There were no lightning bolts from the programming gods. Our desktops didn’t explode. In fact, our code compiled and shipped, and the customers seemed happy enough.
That’s because bad programming isn’t in the same league as, say, licking an electric fence or pulling the tail of a tiger. Most of the time, it works out. The rules are more often guidelines or stylistic suggestions, not hard-and-fast directives that must be obeyed or code death will follow.
Sure, your code might be ridiculed, possibly even publicly. But the fact that you’re bucking conventions adds a little bit of the thrill to subverting, even inadvertently, what amounts to (more often than not) the social mores of pleasant code.
To make matters more complex, sometimes it’s better to break the rules. (Shhhh!) The code comes out cleaner. It may even be faster and simpler. The rules are usually a bit too broad, and an artful programmer can improve the code by breaking them. Don’t tell your boss, but sometimes it makes sense to code your own way.
What follows is a list of nine rules that some may consider unimpeachable, but many of us break often, with both success and pleasure.
Bad programming habit No. 1: Copying
It’s wrong to do it in school. On the job, the rules are not so clear. There are certainly some blocks of code that shouldn’t be stolen. If it comes from proprietary code, don’t fold it into your stack, especially if it’s marked with a copyright message. Write your own version. It’s what they’re paying you to do.
The trickier question comes when the original creator wants to share. Perhaps it’s on one of those online programming fora. Perhaps it’s open source code with a license (BSD, MIT) that permits snagging a function or three. There’s no legal reason stopping you. And you’re paid to solve problems, not reinvent the wheel.
Most of the time, the advantages of copying are compelling and the disadvantages can be limited with a bit of care. The code you get from a reputable source has already had at least one round of thought applied to it. The original author searched for a solution and found something. The loop invariants and the data flow has been worked out.
The tricky questions are whether there are some unfound bugs or some different assumptions about the role or the underlying data. Perhaps your code mixes in null pointers while the original code never checked them.
If you can fix the problems, it’s like your boss is getting the input from two programmers. It’s pair programming without the fancy desks.
Bad programming habit No. 2: Non-functional code
For the last decade or so, the functional paradigm has been ascending. The acolytes for building your program out of nested function calls love to cite studies showing how the code is safer and more bug-free than the older style of variables and loops, all strung together in whatever way makes the programmer happy.
The devotees speak with the zeal of true believers, chastising non-functional approaches in code reviews and pull requests. They may even be right about the advantages.
But sometimes you just need to get out a roll of duct tape. Wonderfully engineered and gracefully planned code takes time, not just to imagine but also to construct and later to navigate. All of those layers add complexity, and complexity is expensive.
Developers of beautiful functional code need to plan ahead and ensure that all data is passed along proper pathways. Sometimes it’s just easier to reach out and change a variable. Maybe put in a comment to explain it.
Even adding a long, grovelling apology to future generations in the comment is faster than re-architecting the entire system to do it the right way.
Bad programming habit No. 3: Non-standard spacing
Most spaces in software don’t have an effect on how the program performs. Except for a few languages like Python that use the spacing to indicate blocks of code, most spaces have zero effect on how the program behaves.
Still, there are obsessive programmers who count them and insist that they matter. One of them once told my boss in the most serious tone that I was writing “Non Standard Code” and he could see it immediately. My sin? Violating the ESLint space-infix-ops rule by failing to put a space on both sides of an equal sign.
Sometimes you just have to think about something deeper than the placement of spaces. Maybe you’re worrying about the database getting overloaded. Maybe you’re worrying about some way that a null pointer could crash your code.
Pretty much any part of the code is more important than the spaces, even if neb-nosed, bossy standards committees have filled pages of rules about the placement of these spaces or tabs.
The amazing thing is that there are several good tools that will automatically reformat your code to adhere to any well-defined linting rules. Humans don’t need to spend time thinking about this. If it’s so important, they can run it through the tool to clean up the problem.
Bad programming habit No. 4: Using goto
The prohibition on using goto
dates to the era before many of the tools of structured programming even existed. If programmers wanted to create a loop or jump to another routine, they would need to type GOTO
followed by a line number. After a few years, compiler teams let programmers use a string label instead of a line number. That was considered a hot new feature back then.
Some called the result “spaghetti code.” It was impossible for anyone to read your code later and follow the path of execution. It was a jumble of threads, forever tangled. Edsger Dijkstra banned the command with a manuscript drolly titled “Goto Statement Considered Harmful.”
But absolute branching isn’t the problem. It’s the tangle that results. Often an artful break
or return
will offer a very clean statement about what the code is doing at that location.
Sometimes adding goto
to a case statement will produce something that’s simpler to understand than a more properly structured list of cascading if-then-else blocks.
There are counterexamples. The “goto fail” security hole in Apple’s SSL stack is one of the best instances. But if we’re careful to avoid some of the gnarly issues of case statements and loops, we can insert good, absolute jumps that make it easier for the reader to understand what’s going on. We can put in a break
or a return
that is cleaner and more pleasing for everyone—except perhaps the goto
haters.
Read more on the next page...