Hacker News new | ask | show | jobs
by kaeluka 3130 days ago
Code duplication can be seen as a "defensive copy". If you duplicate code, the original version can be changed without breaking the copies.

Disclaimer: I'm not making a value statement here :-)

2 comments

In an ideal world, what you want is more like copy-on-write. Share the code until one of the clients of that code needs a change that the others do not, then copy it. In reality, what happens more often is an accumulation of different functionality used by different clients. Copying "defensively" as you suggest can help avoid that problem, but it has the opposite problem of requiring changes to all copies when all clients want the same thing. In my experience, this is the problem more likely to lead to painful mistakes. There is no silver bullet...
Even with "copy on write" there would still be the problem of wether to copy before write or not: requirements for usage A change because someone recently thought hard about that part. Usage B is most likely not on anybody's mind right now andchanging that is quite some effort. It's a problem no matter wether you copy, DRY or something in between.

Maybe some of our processes, language and experience from the version control space (branch, merge, rebase, upstream...) could be ported over to the reuse vs duplication problem. But when you layer that with the conventional use of those concepts in version control, the result would be quite the multidimensional mindbender. With that as a hypothetical baseline, simply guessing a good compromise between abstraction and duplication and then dealing with the consequences suddenly does not seem that bad a fate.

You mean like prototype-based inheritance?
I don't think prototype-based inheritance (or monkeypatching) is any better at avoiding duplication than "regular" Java-style inheritance, and both will only help avoid certain kinds of duplication some of the time.

If you need to modify a small part of a class's function, there's typically no way in a prototype/traditional inheritance language, to say "like the function from the parent class, but with these 5 lines different".

Inheritance of any kind is a handy tool to help with the "whole class files full of pages of identical code with one different method" problem, but a) that's not the cause of a lot of duplication out there, b) you still have to know/care to implement the inheritance, and c) it can come with its own struggles, a la tight coupling to implementations/classes you may not fully control. This isn't a pro-OO or anti-OO screed; just pointing out that inheritance as a means to DRY up code is a limited solution at best.

I don't think so... I'm talking about copying the code itself.
So ctrl-f and ctrl-v using the diff as needed?

I wonder if the man hours wasted on hunting through someone else's code to figure out the bajillion abstracted functions are doing when you are trying to make a change outweigh the minor inconvenience of copying and pasting changes are? Yes the latter introduces more opportunities for errors, but are they more than knowing all your dependencies and ensuring your changes don't break their expectations? Unit tests are only as useful as the man who knows the future.

That's basically what I'm saying: it's unknowable whether copying and pasting and needing to keep all the copies up to date in the future will result in more or less work and bug fixing than re-using code. I think the best solution is for experienced developers to make an educated guess on a case by case basis. But you can't write that into a generic principle.
> In an ideal world, what you want is more like copy-on-write. Share the code until one of the clients of that code needs a change that the others do not, then copy it.

Good point. The problem with that is, of course, that you may not be aware of others existing.

> There is no silver bullet...

+1