Code is a tool for exploring and understanding problems as much as it is about solving them. Sophisticated solutions can't be designed before they are validated.
Code is a tool for exploring and understanding problems as much as it is about solving them. Sophisticated solutions can't be designed before they are validated.
Part of the problem is that it's next to impossible to separate the facts from the religion in software domain knowledge. Software artifacts are simultaneously art, technology. math and religion.
It's also hard to separate the abstract knowledge that is broadly applicable from its original context where it was hard won: the particular operating systems, toolchains and tech stacks.
Even that knowledge which is separable is mired in the jargon of those systems, so that it looks like it is specific to them. If those systems are long obsolete, then it's easy to dismiss anything that is robed in their jargon as being obsolescent by association.
If civil or electronic engineering were like software, then every five years, someone would be reinventing a class B push-pull emitter follower amplifier output stage, or Pratt truss, under different names.
I've got some abstractions out there I wrote early on when I didn't think I coded well and they have lived for years and saved tons of time.
Others don't live long :(
So many times I've taken code that was a mess because someone tried blindly DRY code for the sake of being DRY and rub abstractions on top of it and I've reverted the code back to being simple copypasta and its become so much more clearer and robust. Then you can look at the result and a simple abstraction may pop out which can reduce enough code duplication that the result is satisfactory (it may require a bit more boilerplate in the subclasses or whatever, but nothing likely to be brittle under future fixes).
But an underly-DRY codebase... good luck. Copypasta tends to accumulate minor differences and figuring out if those minor differences matters can become very time consuming.
The DRY version of this is functions/constructors/methods that take a stupid number of parameters, many with unclear purposes.
I'd rather debug code spaghetti by rearranging copypasta to sort out the simple deltas than try to unwind LSP-violating inheritance spaghetti.
Good intentions at every step, but a Frankenstein's monster of a function (or entire class, sometimes) in the end
It's the DRY equivalent of having 20 slightly-different copypastes all over a codebase.
The Django monolith I worked in for some time was like this - 30, 30, 40 parameters on the methods to handle completing a purchase.
It is the aggregation of a dozen different developers each adding a knob to close a ticket/bug over the course of maybe 10 years.
It is better to under-abstract and keep some duplication than over-complicate and miss. Complexity snicks up on you (it is a time bomb).
Welcome to the field of genetics.
A person who possesses music theory can explain why they are composing something they way they are, and suggest better notes to someone who is trying to embellish the music with a harmonization or whatever. Just like the people who held the "theory" of the compiler were able to spot better ways of implementing the ideas of the second group without spoiling the design.