4 ms·
The examples shown in the post aren't wrong because they fail the grep test, they are wrong because they A) capture an uninteresting abstraction that is not lik
by stiff 13y ago
The examples shown in the post aren't wrong because they fail the grep test, they are wrong because they A) capture an uninteresting abstraction that is not likely to see much usage as the program gets more complex, B) mix up domain code with tooling code that if at all gets developed should end up being part of a framework, plugin, base class etc.
The general underlying problem is that a lot of people stick with those "principles" (which are rules of thumb, often weak ones at that) they have read somewhere without developing a real understanding of software design. Slogans like DRY or SRP seem to blind people to often simple forseeable consequences of their design decisions.
Software design boils down roughly to two abilities: one is imagining a great many ways of structuring a program, the other is the understanding of practical consequences of a given program structure. So a good software designer must ask him- or herself: why code repetition is a bad thing? And the answer is that there is absolutely _nothing_ wrong. What is wrong is that a logically or structurally common aspect of the problem didn't receive the recognition in the form of an abstraction (a method, class, variable, interface ...). Then you waste time by not being able to reuse this abstraction, when something about this common aspect changes you are forced to go through fifty places and modify the code, but the worst thing is that there is a limit of the amount of details a programmer can keep in his or her head, and the less you are able to structure your program the more restrictive will be limit of the problem complexity you will be able to tackle. That's the reason software design is at all important.
There are cases however when there is no real logical common denominator to two pieces of code and they are similar practically by accident. It is just as wrong to abstract an accidental similarity as it is not abstract an existing one; soon the requirements change and the abstraction will have to be abandoned, code copied and developed in divergent ways.
Finally, people start attempting metaprogramming way before they had learnt enough about structuring programs using basic means, like breaking things down into classes and methods appropriately, data-driving your programs etc. Yes, this is actually a skill, and unless you rewrite some of your own programs 5-10 times and compare their structure you won't learn it. I also recommend reading some classical books: SICP, Refactoring, Refactoring To Patterns, Effective Java, Programming Pearls.
And the ultimate lessons come from maintaining your own code for a few years.
- andrewflnr 13y agoSo you're saying that code duplication is only (usually) a symptom of failing to factor out a relevant abstraction, rather than something to be fought in itself? On the first reading, it looks like you say "there's nothing wrong with code repetition" and then immediately list all the things wrong with it; instinctively, "a logically or structurally common aspect of the problem didn't receive the recognition in the form of an abstraction" is synonymous with code repetition.
- stiff 13y agoTalking about code repetition is focusing on the wrong thing, consider how metaprogramming is used in the article: it mechanically generates the same code that previously was simply in place in the class. It doesn't make anything simpler to understand, it doesn't allow to modify common logic in one place and in the future it is likely those common "behaviours" will diverge anyway because the similarity is just very weak and superficial. I would instead advise to strive to extract all possible interesting abstractions and if you pushed yourself really hard to do it and there is some repeated code left at the end, it might just be fine to leave it as it is - the cost of removing duplication might outweigh the benefit. In the example posted, position and direction are both vectors, recognizing them as such would provide a much better way of checking for "zeroness" and for negation. It's a nice educational aspect of this toy problem the author seems to not have noticed himself. There is often a similar elegant way out of real-world complex problems that doesn't involve fancy meta-programming but just good abstractions, putting right data in the right place etc.
- Goladus 13y agoThe examples shown in the post aren't wrong because they fail the grep test, they are wrong because they A) capture an uninteresting abstraction that is not likely to see much usage as the program gets more complex My understanding is the point of doing the grep test is to avoid capturing uninteresting abstractions not likely to see much usage as the program gets more complex. If you are a programmer who sometimes loses sight of the program's real goal because you're worrying about code duplication, the grep test might be useful for you.
- 13y ago