We’ve all done it. And we’ve almost all regretted doing it. So its time to talk about an uncomfortable subject for many.
Copying and pasting code.
The temptation is constantly there. You see some code here that works (or at least appears to work). You obviously don’t want to reinvent the wheel, and maybe some aspect of the code makes re-factoring it out difficult. Maybe you agonize about it a little, or maybe you blissfully ignore the dangers. In the end, a Control-C and Control-V later, and that block of code has reproduced it self. The world doesn’t tragically end, everyone you know doesn’t die of a horrible disease, and your system still continues to function. So you figure, hey, copying and pasting code isn’t so bad, and so copy and paste that same line of code again. And again. And again. And before you know it, your computer’s clipboard has become an indispensable tool. Maybe you go even so far as to push others to follow in your copy and pasting footsteps. I’ve seen people put in their documentation something along the lines of “if you want to do x, copy this code from file y”. And the world still continues to go on.
Then, suddenly things change.
You find a bug in that original code you copied. Its an easy fix, except that single bug has now reproduced like a virus, infecting your entire system. Or maybe that code was golden, but the requirements do what they love to do so much and completely change. Again, a quick fix to the original code will fix it, but the copying and pasting has, best case, increased the difficulty of the fix by a factor of the number of times you copied that code. Worst case, different copies will have subtle differences (maybe some are still on an older revision of the change), maybe some are so different you are no longer able to recognize their lineage, but under layers of re-factoring the old functionality still lives on.
We all know this risk, but problem is actually more severe than what I’ve described.
Copying and pasting the same code, the same functionality, the same patterns; it all means you’ve missed a chance to abstract out some part of your system. If you have dozens of classes that follow nearly the same pattern, there is something important about that pattern that needs to be captured at a higher level. Not only will that make your code more maintainable, abstracting out these patterns makes it easier to reason about. You can make better deductions about code that is made up of higher abstractions than code that simply looks similar to that other code over there.
And of course in many cases, copying and pasting code is a symptom of a larger problem, a lack of understanding of the original code. It is too easy to find code that does something similar to what you want it to do, and then copying it verbatim. But is that “something similar” exactly what you want? Maybe its doing something subtly different, something you might not need or even want. Maybe there were valid assumptions made when that code was originally written that you have no business making. But if you took the easy route and just copied it without understanding it, you will have no idea that is the case
In other cases its a sign of laziness. Not the type of laziness that avoids work, in fact re-factoring to prevent the need for a copy and paste job is usually less work. But a more intellectual type of laziness. Work that just involves repeating something someone else did is easy, whereas if you can easily get past that easy part you are stuck with more challenging work. Moving code around is easy, solving problems is the hard part.
Of course its not always your fault. Maybe you are working in a language that makes certain kinds of patterns difficult to abstract, maybe even to the point it appears its actively resisting the concept of you being productive (I suppose it could be worse for Lambda, considering what is happening with Jigsaw). Are there are plenty of times when what you are copying actually is too small to be successfully reused. I’m not saying never copy and paste code, or never reuse the same patterns or functionality. Just next time you catch yourself doing it, please stop and ask yourself the following question:
Is there a better way to do this?