|
There are times when you simply have hard problems. For example, take code generation (I actually have in mind a SQL query generator, but a compiler back end would do just as well). The problem is already abstract - the input is code, you're naturally writing code that manipulates code, like you would with macros or reflection. The problem is complex: you can generate simple code, but it won't perform well. There's irreducible complexity here that cannot be simplified away. You'd also like the code generation itself to be fast. That puts a limit on how much you can break it up into parts that can be understood individually and in isolation. Optimization works in opposition to abstraction because the optimal often requires steps that span multiple abstraction layers, and often requires multiple instances of the specific over few instances of the general. Personally, I think the two biggest reasons code becomes unnecessarily complicated these days are (a) testing and (b) local modifications. Unit testing in particular encourages over-parametrization so that dependencies can be replaced for the purposes of testing; while normal software maintenance under commercial pressure leads to local modification because nobody has time to understand the whole. People instead make conservative local changes by adding parameters, extra if-statements, local lookup maps, etc. I've found elegant solutions are often on the other side of a hill from over-engineering. You write specific solutions, then you climb the a hill of abstraction as you add layers, indirections, parameters etc., until you reach a summit, where you can see the whole, and can then start boiling things back down again, only retaining abstraction where it's actually necessary, or perhaps replacing multiple abstractions with a single more powerful abstraction (I've found this to happen a lot with monads; another one is converting control flow into data flow). |
Yeah sometimes you do, and that is exactly the kind of problem that is irreducibly complex, but I think new kinds of problems like this don't tend to crop up in the wild very often and when they do they tend to show up in subtle and non-obvious ways.
The problem you've described is far from a new problem - it's the same problem space that is covered by ORMs. Furthermore, if I were working on a team where a developer has uttered the words "I've created my own ORM" (or something to that effect), my face has probably already landed in my palms.
The rest of what you wrote I'm in vigorous agreement with though- especially the parts about unit testing, local modifications and "the other side of the hill". Seen all of that.