I certainly have had these thoughts. It’s the reason why most of the things I bake aren’t very edible… When it comes to programming, these thoughts arise too. What if I wrote this part as a separate function? If I hard-coded this bit over there, would it make the code easier? Can I rewrite those ten ugly lines into two elegant ones? There are no recipes in programming, but there are best practices. They’re not precise like a recipe, but clear enough that it’s evident if you haven’t implemented them. Like with recipes, some best practices get repeated over generations of programmers. Sometimes it makes sense to do so; sometimes that’s nothing more than a tradition. Cargo cult programming, if you wish to call it that way. But eventually, even the coolest tradition dies out or evolves into something more useful. The same will happen with some, but not all, best practices in programming.
Simultaneous “don’t repeat yourself” and separation of concerns doesn’t work
Recently I reviewed some of my old code and noticed that the same four lines of code popped up three times in the same file. Now, any person who has studied any formal computer science (not me, I did physics) will tell you that this is silly because you need to keep your code DRY. Don’t Repeat Yourself has become a mantra of sorts. I’m not a computer science major, but I do read a bit, and I’d internalized that mantra. So I took those four lines and put them in a function. Then I noticed that I couldn’t do that so easily because those four lines weren’t completely identical. A small change on the third line meant that I’d have to add at least one option to my new function. I’d also need an if-clause and perhaps a new boolean parameter to invoke that option. That would’ve made the code as complicated as it was before. But then I noticed that those four lines always get invoked after calling other functions, two different functions across three different places, and so I thought I might as well add the four lines to those functions. This worked well because the small change on the third line would be handled by each of the preceding functions, and one of the two already contained a matching parameter. This did simplify my code slightly. I did end up repeating myself, but only twice instead of three times. And I violated the Single Responsibility Principle because my two functions were doing more than they were advertised for. You could argue that I probably just wrote bad code and that there might be much more elegant workarounds for what I was trying to accomplish. And these workarounds might have even satisfied both principles. Fair enough. It’s hard to disprove a claim like that. But programmers aren’t paid to write the most elegant and beautiful code of the decade. They’re paid to make something work. My project works. And more code-cosmetics would cost me valuable time that I’d rather spend on other projects that aren’t working yet. Maybe I’m just so dumb I can’t even get two programming principles two work. But I guarantee you that there are whole swathes of programmers that are on a similar level as me. Swathes of people who can’t get DRY and SRP to work together either. It’s unlikely that this would cause DRY to dry out (sorry, the pun had to be). It’s an extremely useful principle for example in functional programming, which is taking up steam these days. The Single Responsibility Principle, on the other hand, might become rarer. Think about neural networks, for example. They don’t figure out one single thing. The more sophisticated ones understand, and react to, millions of different images, text messages, or complicated proteins. That’s the opposite of SRP. In other words… SRP is DRYing out.
Please reinvent the wheel from time to time
Like DRY and SRP, this practice was popularized by people with good intentions. But that doesn’t change the fact that it isn’t always sensible to implement. The idea is that if a solution to your problem already exists, you should use it. It’s probably less buggy and more efficient than your home-cooked solution. There are a few problems with this thought. First of all, existing solutions rarely match your specific problem 100 percent. So it’s quite likely that you’ll solve, say, 75 percent by importing a solution or a package that addresses your issue. But you’ll still have to do a substantial part of the legwork yourself, plus testing, debugging, and maintaining. Second, existing solutions often have more than one feature. And you’ll probably not use all the features. So you’ll be introducing a certain amount of superfluous code to your project, which makes it harder to understand and harder to maintain. You could have avoided that by custom-building your own. Third, beware of incorporating open-source solutions in proprietary projects. This is a violation of copyright and can, in the worst case, get you into legal trouble. If you use open-source code in your project, your project should be open-source too. Finally, reinventing the wheel won’t guarantee freedom of bugs anyway. Even if it’s tried, tested, and up-to-date (which is rare enough), you still have to incorporate it right and write the boilerplate code around it. So why not write your own custom solution, make a few mistakes in the process, and learn from them? These kinds of lessons can be extremely valuable, and they’ll make you a much more valuable programmer in the long run.
Quantity over quality
Writer Sean Kernan (he’s great, check him out) has a great piece about how you should push for quantity, not for quality when you’re doing creative work. For writing, this means that if you write one article a month and polish it until it’s great, it’s going to be around about okay. Not great, because you haven’t used your writing muscles very much with only one article. But not bad-bad because you’ve polished it up quite a bit. But if you wrote 30 articles in one month, it’s quite unlikely that all of them would only be bad-bad or okay. Some of them will be great, and one or two of them might even be excellent. Of course, you haven’t had the time to polish your work as much, but your writing muscles will be Arnold-Schwarzenegger-size once the month is over. And you’ll have had the time to make every possible mistake, from typos to treading on other people’s feet, and hopefully internalized the lessons. Now, you might object that programming is rather different to free writing. Yes, programming is more technical than writing and you might need a lot more background knowledge to even start. But programming is, in its essence, quite a creative discipline. Programming is basically about finding interesting, elegant, and efficient ways to solve problems with a computer. That’s creative! Detractors might say that 100 pieces of mediocre code are still mediocre, and one piece of great code is therefore better. But seriously, if you have 100 shots surely you’ll shoot one in the right direction! By the laws of statistics, if 100 pieces of on-average mediocre code, ten will be great and two will be excellent — and that’s better than one piece of great code. So code more, make more mistakes, and learn more.
Best practices turn you into a complacent a-hole
It boils down to this: You‘re free to follow all best practices. But they might limit your thinking and blind you to more innovative solutions. If you really want to stand out in a positive way, use best practices as guidelines. Break those guidelines when that seems appropriate to you. People who always follow the rules become complacent. And complacency, over time, kills success. Start breaking the rules and you have a shot at joining the great heads. Repeat yourself if that’s better for you. Leave your responsibilities tangled if that’s easier to maintain. Code your own solutions instead of importing existing ones that don’t fit perfectly. And code more. Much more. Even if it’s bad or buggy. There’ll be a few gemstones in the mess you create. This article was originally published on Medium. You can read it here.