Take almost any programming class, and your instructor will at some point mention the importance of writing “clean code.” That might sound intuitive enough. But when you start to break down clean code principles, you quickly realize that what counts as clean code is very difficult to explain.
For one thing, ask different programmers to define clean code, and you’ll almost certainly get a different set of answers. Probably the most oft-cited definition of clean code (at least for the current generation of programmers) is the one laid out by Robert Martin in his 2008 book, Clean Code.
In general, Martin’s book is a great starting point if you’re looking for best practices to follow when writing clean code. But it has some limitations. One is that Martin was writing primarily for developers working as part of larger teams. For him, clean code meant code that was easy for other people on your programming team to understand.
Making sure others can interpret and modify your code easily is generally a good idea. But whether it actually matters in practice can vary. Not everyone writes code that other people need to understand.
Plus, there is a great deal of subjectivity in determining what makes code understandable to others, and which conventions to follow in order to achieve understandability. For example, most programmers know what “i++” means, and prefer to use it to increment integers instead of writing out a more tedious phrase like “i=i+1.” But i++ is a shorthand, and shorthands breed ambiguity and uncertainty. If you are truly concerned with maximizing the readability of your code, shouldn’t you stick with the longer, more tedious formulation?
Modularity and Simplicity
Another school of thought suggests that clean code is code that is modular and simple. That’s the logic expressed in this Medium article, for example, which argues that clean code “is focused--each function, each class, each module exposes a single-minded attitude.”
Simplicity certainly has value. But, here again, I don’t think that every programmer would agree that simplicity should be your primary focus in writing code. Simplicity often has tradeoffs. For example, a codebase that consists of many small, simple functions or classes is likely to be more difficult to integrate, build and deploy than one that consists of fewer moving parts.
That’s not to say the extra effort isn’t worth it. Maybe it is. But you need to evaluate this on a case-by-case basis.
Another term you often hear frequently in conversations about clean code is “elegance.”
What exactly elegance means in the context of coding depends on whom you ask, of course. But, in general, when programmers talk about elegant code, they mean code that is as short, sweet and clever as possible.
To most programmers, a long string of code that crams a bunch of conditional operators into a single line is not very elegant. A neat, multi-line conditional if/else clause would be considered more elegant.
The problem with the idea of elegance is not just that elegance is hard to define, but that elegant code is often at odds with efficient code. Your multi-line conditional clause will require more keystrokes to write out than a one-line statement that achieves the same functionality. It could also make your source files larger.
In a roundabout way, these drawbacks conflict with the very idea of elegance: The more elegant your code in appearance, the less elegant the process of writing and managing it.
Best Practices for Writing Clean Code
The bottom line in any discussion of clean code is that clean code is in the eye of the beholder. And the beholder could be the original author, a new maintainer who becomes responsible for the code when its original programmer gets a new job, or just a curious teenager browsing your GitHub repository.
To make things more complicated, many attempts to define clean code incorporate terms or ideas that are themselves highly ambiguous, such as simplicity and elegance.
Still, I do think there are at least a few basic best practices that you can follow to create code that is truly clean in most people’s eyes:
- Indentation: Some programming languages (like Python) are pretty strict about forcing you to indent in a clean way. Others let you do whatever your heart desires (which is why, for example, so much automatically generated HTML code is ridiculously hard to read). If you care about cleanliness at all, you’ll establish a basic policy regarding when and how much to indent your code, and you’ll follow it for every line of code you write.
- Naming: As a best practice, use names for variables, classes and other components of your code that make sense and are easily readable to human beings, including non-native speakers of your language. It might require a few more keystrokes to name your variable $database than $db or just $x, but the meaningful name will make it easier for other people to read your code (and for you to remember what the code does).
- Comments: Comments are free, and there is no reason not to use them judiciously to help yourself and others understand your code. A few short comments can go a long way to make otherwise byzantine code easy to understand. Comments might not make your code itself very clean, but they can help make up for a lack of cleanliness.
- Consistency: No matter which coding practices you decide to follow, be consistent. I’d even argue that it’s better to be consistent even if you write unclean code in some respects (like failing to indent) than to follow clean coding practices sometimes but not others.
Beyond these handful of pointers, I tend to think that most clean coding practices are subjective, or depend largely on context (like which language you’re using, or whether your code is a personal or corporate project). Getting everyone to agree on what counts as clean code is a fool’s errand.