I, for one, don't blindly copy and paste code. Code collects entropy over time; if it's been around for a while, it almost invariably can be improved. Copying and modifying is cargo-cult coding in the small and one of the fastest ways to create a codebase where you have no idea what the code is doing.
Adding process and standardization around this seems like a patch on a dysfunctional coding culture. Standardization frequently ends up on something that isn't the best way, and with web development in particular, is likely to be outdated in a few months. Requiring meetings to change standards to improve code has got to be a toxic working culture.
Yes, but blind to what? The coder is blindly manipulating symbols[0]. What if the code produces the artifact you desire? I'm not sure anyone really blindly copies and pastes. On the flip side, if you forget what you wrote in a month or two, how is that outcome different than copying and pasting in the first place?
Copy and paste code out of the same repository, modifying it slightly? Surely the more appropriate thing to do in most cases it to make that code generic, available as a function, and then call it from the two places that now need it?
It sounds like it is the code review of future commits that needs to be fixed here.
I copy and paste code all the time, but almost only for tests. I don't think tests should be abstracted too much. I don't appreciate having to work to understand what a test is doing, and when the test gets too long it's a sign you're testing at the wrong level.
Ok, let me give you an example, where my instinct would be to copy and then modify:
We have a library that requires initialization, action, and then freeing of resources. Initialization involves creating and filling in a struct and/or passing parameter values to an initialization function. After that it is necessary to check for success/failure. That's for initializing the library. Then something similar is done to initialize an object we want to manipulate.
I would begin with the copied code, replace the appropriate values in the initialization, replace the error handling, replace the action, and keep the freeing of resources as is.
>place a very high value on what ends up checked-in to a source code repository. The reason for this is very simple: once code gets checked-in, it takes on a life of its own.
I would modify this slightly and say code that's added to important public branches designated as master, qa, integration, etc should have a very high bar for quality. The other "experimental", "sandbox", etc branches would be understood by the team to have suboptimal code. Yes, it doesn't prevent people from Ctrl+C+Ctrl+V'ing the bad code but at least the developer's work-in-progress code has been backed up to a wider repository than just his laptop. (Yes, the programmer should be backing up files to USB flash, or corporate LAN, yada yada, but disciplined backups outside of repository commits often don't happen.)
That said, cargo culting bad code is definitely a problem. It doesn't matter of the source code has any of these comments:
//This following is experimental. DON'T COPY IT!
//!!!Do not reuse the following loop. It is O(N) instead of O(log N) and I haven't optimized it yet!!!
It doesn't matter how many scary exclamation points and uppercase characters are used in the warning. It will be ignored.
Even if you using language level guards instead of comments such as #pragmas or metaprogramming (if this_function_name == "JohnExperiment3"), people will just ignore the guards and Ctrl+C+Ctrl+V the "bad" source code lines they need. The infamous example of "if windowsos.version begins with "9" is copied all over the place.
> Even if you using language level guards instead of comments such as #pragmas or metaprogramming (if this_function_name == "JohnExperiment3"), people will just ignore the guards and Ctrl+C+Ctrl+V the "bad" source code lines they need. The infamous example of "if windowsos.version begins with "9" is copied all over the place.
Hmm, could this be the reason for windows 10 after 8?
This is a great article, something I have noticed but failed to place into a good metaphor like this.
The other place this happens is in online code snippets for blogs and the like. If you need a way of doing things, you often search. If you find it, you'll probably copy it. If you find the same thing twice, you'll think everyone does it this way.
So the lesson there is to always be careful about code you put into blog posts and stack overflow answers and the like. If you cut a corner, get sloppy with a naming standard or fail to put in basic checks, you're spreading landlines across the world and there's no way of recalling them, because nobody comes back to review a solution they found online.
"The original engineer knew that they hadn’t properly solved the problem and left it as a landmine for someone else. It just so happened that I stepped on it and now couldn’t remove my foot until it was properly disarmed."
The problem with these warnings is that their authors assume there is a better, economically viable way of doing a particular thing. When it was economically not viable for the original author to find and apply the ideal solution, why I or my project manager spend the time to find the "real" solution (which may or may not have any effect on the end user)?
There's not even a guarantee that the "real" solution would be more maintainable or less complex than the quick fix (for example, what is the "real" solution to fixing a confirmed bug in some Swing base class?). Most of the really dirty fixes I've encountered fall into this category.
This is a good article, I'm sure I'll find myself saying "no bad bunny code" soon.
I've encountered this phenomenon and there are a few situations where it can feel natural or correct to copy and paste code. While I can't say these are great reasons, they do merit being considered.
0. QA concerns. You can't just modify/change logic without triggering a need for QA to re-check. This is in fact, one of the biggest stumbling blocks for code quality in a company. You just can't refactor as needed, it has to be planned for and paid for. There are times when you're basically stuck using bad/logic and just extending it.
1. You're a guest in the code. You're just working on this feature for one iteration, and the other guy who will likely be on the project for the rest of the year wrote the bunny code. I wouldn't change how he does things, I'd instead talk him and let him know there's a better way. I wouldn't implement a second type of fix.
2. It's unclear what direction the primary authors want the codebase to grow in. For instance do you use library level functions to accomplish tasks the language syntax can? (for loops vs an iterator function). Some prefer one over the other. I would just follow the style I see
3. Styleguide logic. E.g. the code should look as much as possible like it's written by one person. While I know this rule applies to indentation and visual appearance. I think it's fair-ish to apply to it to logic as well.
These are a few things to think of, but I agree with the author of the post, be careful, this code will multiply.
> In my current role at Box, I’m famous for repeating the phrase, “no accidental standards.” We don’t accept that things are “the way” just because they pop up in a couple of places. When we see this happening, we stop, discuss it, and either codify it as “the way” or disallow it. We then update code appropriately before it gets too far. Through automation, code reviews, and code workshops[1], we are able to keep an eye on the code and make sure we’re all on the same page.
no.
There's a faulty assumption here: that code in a repo should have a pattern. That there's a Way of writing code that should be followed within a company. That it's acceptable to believe code already checked in is the Way.
no.
Having worked in a team that was very serious about this approach advocated by the OP, what happens is that opinions about the Way change, so the fad from two years ago is no longer the Way, but it still ghosts on through the code base.
You will encounter many ways of writing code in many repositories through your life.... the ideal Way of the code is to be able to write the code needed, how it needs to be written, without bothering too much about the Way Of the Mandate (but don't copy and paste).
It's slightly Tao, I think. The Way that can be described is not the Way...
[+] [-] barrkel|11 years ago|reply
Adding process and standardization around this seems like a patch on a dysfunctional coding culture. Standardization frequently ends up on something that isn't the best way, and with web development in particular, is likely to be outdated in a few months. Requiring meetings to change standards to improve code has got to be a toxic working culture.
[+] [-] 0xdeadbeefbabe|11 years ago|reply
Yes, but blind to what? The coder is blindly manipulating symbols[0]. What if the code produces the artifact you desire? I'm not sure anyone really blindly copies and pastes. On the flip side, if you forget what you wrote in a month or two, how is that outcome different than copying and pasting in the first place?
[0] http://blog.airover.ca/2014/06/programming-blindly-manipulat...
[+] [-] cmpb|11 years ago|reply
Edit: without* standardization
[+] [-] rlpb|11 years ago|reply
It sounds like it is the code review of future commits that needs to be fixed here.
[+] [-] juliangregorian|11 years ago|reply
[+] [-] im3w1l|11 years ago|reply
We have a library that requires initialization, action, and then freeing of resources. Initialization involves creating and filling in a struct and/or passing parameter values to an initialization function. After that it is necessary to check for success/failure. That's for initializing the library. Then something similar is done to initialize an object we want to manipulate. I would begin with the copied code, replace the appropriate values in the initialization, replace the error handling, replace the action, and keep the freeing of resources as is.
[+] [-] jasode|11 years ago|reply
I would modify this slightly and say code that's added to important public branches designated as master, qa, integration, etc should have a very high bar for quality. The other "experimental", "sandbox", etc branches would be understood by the team to have suboptimal code. Yes, it doesn't prevent people from Ctrl+C+Ctrl+V'ing the bad code but at least the developer's work-in-progress code has been backed up to a wider repository than just his laptop. (Yes, the programmer should be backing up files to USB flash, or corporate LAN, yada yada, but disciplined backups outside of repository commits often don't happen.)
That said, cargo culting bad code is definitely a problem. It doesn't matter of the source code has any of these comments:
//This following is experimental. DON'T COPY IT!
//!!!Do not reuse the following loop. It is O(N) instead of O(log N) and I haven't optimized it yet!!!
It doesn't matter how many scary exclamation points and uppercase characters are used in the warning. It will be ignored.
Even if you using language level guards instead of comments such as #pragmas or metaprogramming (if this_function_name == "JohnExperiment3"), people will just ignore the guards and Ctrl+C+Ctrl+V the "bad" source code lines they need. The infamous example of "if windowsos.version begins with "9" is copied all over the place.
[+] [-] yetihehe|11 years ago|reply
Hmm, could this be the reason for windows 10 after 8?
[+] [-] brc|11 years ago|reply
The other place this happens is in online code snippets for blogs and the like. If you need a way of doing things, you often search. If you find it, you'll probably copy it. If you find the same thing twice, you'll think everyone does it this way.
So the lesson there is to always be careful about code you put into blog posts and stack overflow answers and the like. If you cut a corner, get sloppy with a naming standard or fail to put in basic checks, you're spreading landlines across the world and there's no way of recalling them, because nobody comes back to review a solution they found online.
[+] [-] nthcolumn|11 years ago|reply
This is my life.
[+] [-] _pmf_|11 years ago|reply
There's not even a guarantee that the "real" solution would be more maintainable or less complex than the quick fix (for example, what is the "real" solution to fixing a confirmed bug in some Swing base class?). Most of the really dirty fixes I've encountered fall into this category.
[+] [-] progmanal|11 years ago|reply
[+] [-] roneesh|11 years ago|reply
I've encountered this phenomenon and there are a few situations where it can feel natural or correct to copy and paste code. While I can't say these are great reasons, they do merit being considered.
0. QA concerns. You can't just modify/change logic without triggering a need for QA to re-check. This is in fact, one of the biggest stumbling blocks for code quality in a company. You just can't refactor as needed, it has to be planned for and paid for. There are times when you're basically stuck using bad/logic and just extending it.
1. You're a guest in the code. You're just working on this feature for one iteration, and the other guy who will likely be on the project for the rest of the year wrote the bunny code. I wouldn't change how he does things, I'd instead talk him and let him know there's a better way. I wouldn't implement a second type of fix.
2. It's unclear what direction the primary authors want the codebase to grow in. For instance do you use library level functions to accomplish tasks the language syntax can? (for loops vs an iterator function). Some prefer one over the other. I would just follow the style I see
3. Styleguide logic. E.g. the code should look as much as possible like it's written by one person. While I know this rule applies to indentation and visual appearance. I think it's fair-ish to apply to it to logic as well.
These are a few things to think of, but I agree with the author of the post, be careful, this code will multiply.
[+] [-] progmanal|11 years ago|reply
[+] [-] tie_|11 years ago|reply
[+] [-] PopeOfNope|11 years ago|reply
[+] [-] pnathan|11 years ago|reply
no.
There's a faulty assumption here: that code in a repo should have a pattern. That there's a Way of writing code that should be followed within a company. That it's acceptable to believe code already checked in is the Way.
no.
Having worked in a team that was very serious about this approach advocated by the OP, what happens is that opinions about the Way change, so the fad from two years ago is no longer the Way, but it still ghosts on through the code base.
You will encounter many ways of writing code in many repositories through your life.... the ideal Way of the code is to be able to write the code needed, how it needs to be written, without bothering too much about the Way Of the Mandate (but don't copy and paste).
It's slightly Tao, I think. The Way that can be described is not the Way...
[+] [-] progmanal|11 years ago|reply
[+] [-] Radle|11 years ago|reply
trust me, they also do when you look.
[+] [-] contiver|11 years ago|reply