Code Copying: Good or Bad? ----- Another of the HiringPatterns: Hook prospective programmers up to all kinds of sensors, nodes, etc., and then say the phrase "Copy and Paste". The closer their reaction resembles death, the more likely their candidacy. ---- Also a time saver for those who are using a graphical user interface such as Windows, saving keystrokes and time. When combined with editing of the pasted object, such techniques can be productivity aids. BelieveItOrNot, people other than programmers use this technique quite effectively every day. -- DonaldNoyes ---- With respect to productivity, I respectfully disagree insomuch as you forget: OnceAndOnlyOnce. Note that OnceAndOnlyOnce imposes severe constraints and a controlled environment. It does not apply to such things as words, phrases, quotes, computer commands, a WikiWord (as opposed to the page to which it refers), words used in a language, iterative structures, etc. One must distinguish between definition and usage. But even definitions are modified by signatures. ''No, it applies everywhere to every piece of PrimaryInformation, including variable, class, module, file, field names. When you put table name inside field name it's clear violation of once and only once because you should not duplicate table name inside any other name, or in general, any name inside any other name. I don't like naming style when people put variable types as part of variable names. If variable name contains class name or any other piece of information which introduces additional dependency on it, then it violates once and only once. -- AlekseyPavlichenko'' Editing this page is a perfect example of the use of Copy and Paste, where the Page is copied in present form, is altered, and is saved in new form (pasted). Copying this page from the WikiServer at C2 and pasting it via the browser to the screen you are now reading. Rigid compliance to dogmas like OnceAndOnlyOnce would lead to unwanted situations. A bowl of soup served once and only once would not be very nourishing. If the Print command is used once and only once, there would not be the need for but one sheet of paper, one printer, one cartridge (ink or toner). ''I disagree. When we print, we know that we can always reprint (at least with a well-designed system), which means that whatever we print we can throw into garbage at any time, which defines a printed piece of paper as SecondaryInformation and we don't need to apply OnceAndOnlyOnce here. At the same time, if somebody writes something on this piece of paper, we can not throw it away any more and it becomes PrimaryInformation and it makes it from hard to impossible to separate primary and secondary information using scanning and recognition. Only if we fail to extract primary information here do we have violation of once and only once.'' ''Same logic applies to previous sample with a copy of WikiPage, but in that case it's easier to separate primary information from secondary.'' -- ''AlekseyPavlichenko'' In a society where duplication and multiplication can be a GoodThing, CopyAndPaste rules! ---- CopyAndPaste is the root of evil in programming. -- AhnKiYung So don't do it! I however am not a programmer first and foremost, and for me the accomplishment of actual work, successful completion, and timeliness, depend greatly on the usage of the time saving method of copying and pasting. antonym: GeneralizeOrGenerate ---- I don't like copy-and-paste, but the alternatives require a skill and experience level higher than many companies want to pay for. If staff's skills cannot handle decent factoring, then one is often stuck with copy-and-paste. One place I worked for got on my case for refactoring a situation with a duplication factor of 8. They had some developers in the past who had problems reading and modifying highly factored code (not mine) and it caused some major stirs. '''I reluctantly have to agree with them somewhat'''. There are several risks or downsides to refactoring: * Other readers sometimes cannot handle the higher abstraction or indirection, requiring higher-skilled (more expensive) developers. Companies want PlugCompatibleInterchangeableEngineers. Skilled people are hard to find, not necessarily because there are so few, but because they are hard to detect. And once found, a department may have difficulty holding on to them because of HR's wage restrictions and other office politics. **''I've not encountered these programmers who can't handle simple refactoring. Perhaps they should find a job they are better suited to. NickKeighley'' * Good abstractions and refactorings are often hard to get right. Factoring can be messy too if not done skillfully. I have to admit to occasionally making software that was hard to modify because I over-factored the "wrong" things. I was unable to anticipate the kind of changes that later kicked the design in the nuts. I've improved my estimation skills to reduce these, but it is hard to train others for such. That knowledge generally comes from experience alone and is hard to document and explain. **''I think you exaggerate how difficult this is. Refactor what you have. Reorganise it when (and only when) the requirement changes force you to NK'' * The nature of change is that sometimes it will just not favor some kinds of factorings (LifeIsaBigMessyGraph) creating DiscontinuitySpike''''''s. Although it may reduce the average modification effort, the occasional spikes make it more difficult to estimate the time and cost of change. Managers don't like uncertainty. **''I don't observe this. NK'' * It may require strong domain knowledge to know what to factor when, but there is the complex issue of WhyIsDomainKnowledgeNotValued. **''refactoring rarely requires domain knowledge NK'' * Offshoring has made labor cheap enough that communication is the bigger bottleneck, not the effort to find and make the same change to multiple spots. **''common source repository and email. And yes I have worked on projects where half the team were in a different country. NK'' * Languages or tools may not be conducive to good factoring. For example, languages that lack named parameters may require finding every instance of a function call to add new parameters, or result in the need to pass objects and/or associative arrays instead of the simpler positional function call in order to have parameter flexibility. **''this is why perl was invented. NK'' * FutureDiscounting. The cost of tomorrow's mess is "discounted". I cannot technically argue against this popular accounting principle. **''but when you see the same problem over and over maybe it is time to do some maintenance. If the roof leaks, fix it. NK'' * Many companies do not want to pay for refactoring effort. **''don't tell em. NK'' As a developer, excessive copy-and-paste bothers me. But from a manager's or owner's perspective the cost of dealing with duplication may perhaps still be cheaper than the alternatives. The nature of office politics and limits on staffing flexibility play a role in this. I will generally factor my own code, but will not be militant about insisting on it with others. An example experience was in trying to make a general HTML pull-down list utility. Variations kept popping up and adding them to the util turned it into a SpruceGoose. Example features added over time: * Indicate selected parameter besides first * Results from a query/DB. * Unions of both query list and supplied list (for custom groups/excepts, etc.). * "Single dimension" option where the "value" was the same as the description for longer lists so that I didn't have to duplicate value/label pairs. Other developers looked at utils like this and gave me the evil eye. I had to agree that I deviated from KeepItSimpleStupid. The implementation was not the only problem; for the interface was large and awkward. What I ended up doing was making one simple version and keeping the complex one around. Each site or project tends to have certain conventions that favor a few common sets of the features. Thus, I created an environment-tuned version for each project using old-fashioned copy-paste-and-modify. Those lists that deviated from the list util were simply hand-coded with strait HTML. (Related: HelpersInsteadOfWrappers) The alternative to trying for The Ultimate Generic Thing is some amount of CopyAndPaste. -- top ------ I just encountered a situation that is sticky. The data entry form and the read-only report version of the same form are very similar. Thus, I used the same programming code for both. However, there were many nitty-gritty differences that required addressing. For example, the input screen in some placed needed more explicit text to explain the input rules. Also, there were subtle formatting differences between the two because displayed text may take up a different amount of space than an input prompt. I handled these by putting in a bunch of IF statements, such as IF INPUT_MODE THEN {...} ELSE {...}. This has made the code kind of cluttery. It is fine by me, but often others simply create the input form and then clone it (CopyAndPaste) and then modify the display-only version. It results in a lot of code duplication, but rids the mode-based IF statements and thus is cleaner. I could not make a strong case against the copy-and-paste version. The alternative is not a clear improvement. I don't think sub-classing would work either because the differences are hard to partition in any clean, standard way. What is different for one form section may not be for another, which has its own idiosyncratic variations. The differences are as if somebody tossed darts in the dark. The polymorphism would be single-use. For this reason, a bunch of sub-classes would be worse than a bunch of IF statements in my opinion. -AnonymousDonor ''In general, OnceAndOnlyOnce requires a merging of the different contexts in which the information is used. The merge introduces an overhead. In the example above, the overhead are the IF statements added for the different contexts. Another solution would have been to have two different skeletons for the two pages and refer to the common parts through functions; also this solution would present considerable overhead. A refactoring is only good if the overhead of merging is limited.'' - ArnoutVandecappelle To solve that overhead IDE needs to visualize merged information and be able to hide/show overridden blocks. Also it has to allow editing of anything in such view. Visual Studio 2013 PeekDefinition came close to solving that problem. Good job from Microsoft and one significant step in the right direction. Another thing that IDE should allow is to mark regions with attributes and let developer show/hide all regions of code marked with that attribute. For those unfamiliar with C# there are #Region ... #EndRegion blocks that allow to expand/collapse fragments of C# code. Also there are attributes in C# that can be applied to methods, classes, etc., but not to #Regions. I agree that without these important IDE features having many IF statements or methods reduces simplicity and readability and if % of differences is higher than 60% then it starts to make sense to copy&paste. Main reason of copy&paste for good devs these days is lack of good IDE. Damn, it's already 2014 and Microsoft is only coming close to allowing devs to follow OnceAndOnlyOnce in practice. What a shame for such a wealthy giant. I've seen editor that already solved that visualization problem in 1994. It allowed not only show/hide aspects, but also showed them in different colors and, of course, allowed inline editing. It looks like programming is stagnated for 20 years already. What a shame. -AlekseyPavlichenko ---- If the code you are copying has a bug in it. You have just duplicated that bug and now forced that bug's fix to require a change in two places. BrianLeahy ---- I understand copy and paste is 'evil', but I still feel that it is acceptable to save a few keystrokes with println statements and introducing new 'if-else' blocks, provided you are not introducing bugs or causing maintenance problems. ---- See also: CopyAndPasteProgramming, CloneAndModifyProgramming, ClassificationProblem