There's turds and turds. I've seen many of them and no two turds are alike:
1. A long time ago, we had this turd of a hardware abstraction layer that is every systems developer's nightmare. Windows drivers behind a middleware, with COM and whatnot. Support for USB devices, spanning back to Windows 98. No one dared touch it unless absolutely necessary. Fortunately, no one needed to touch it too often. The functionality it offered was rich enough that the trickier logic could be implemented at application level; it decreased code reuse to some degree, but then again, this was a critical enough piece of software that the time wasted by duplicating some logic among applications was offset by the testing effort required for changes in the HAL behemoth. Most of it was okay-ish, too; it crashed under a few circumstances, but not mysteriously -- we sort of knew where the bugs were, but workarounds were available and they were generally deemed good enough.
This was a reasonable kind of turd. I mean, yes, there was technical debt in it, Jesus, it had comments like "TODO: This looks ugly but for some reason it's the only way to make it work on <some Windows 2000 build>. Maybe figure out a cleaner way?", but it didn't really bother anyone. The code was architected so that technical debt piled up on separate shelves, too. The PCI (not -X. PCI. Plain PCI) stuff, in particular, was only touched by one or two people -- but it was perfectly possible to work on other pieces of that code without breaking the drivers for those weird PCI peripherals.
2. I was responsible for one of these turds. A while ago, we had to do a lot of fancy, detailed documentation for a custom logic design. This was going to be implemented in an FPGA which was going to sit in a pretty advanced medical device -- so you spec everything before writing a single line of code.
One of the things I wrote to help me was a tool that sucked in the timing diagrams in our docs (docs were in LaTeX, diagrams were in some markup language) and generated the Verilog code that put out those signals. This was a bunch of Python code, not too hairy, but it hardcoded every single assumption I could make. It started as a tool I'd made for myself; it was reluctantly promoted to a tool that everyone used.
Some folks tried to adopt it in other projects as well but honestly, the damn thing just wasn't up to it. I suggested to (my, by this time, former) colleagues that they'd probably be better off picking a standard markup language for the timing diagrams (maybe TDML?) and write something that was going to be useful forever, more or less from scratch. Or, if not, get a commercial, off-the-shelf thing that does exactly that, written by people who were paid to write exactly that. The time, people and resources for either of these options turned out to be pretty hard to secure, though, so they ended up polishing the half-bad Verilog code by hand. Still better than writing it all by hand, I suppose.
Frankly, this was at least an excusable turd. It was never meant to be used for so much. It got promoted from "a developer's hack" to "project infrastructure" through a combination of short-sightedness, lack of awareness of better options and bad communication, mine included. But it did provide some value and, honestly, removed none -- it sucked in the end, but it still sucked less than the other alternative that was actually available.
3. And then there's real turds. Like, there was this module I saw a while ago, as part of a bunch of firefighting meetings because the original developer had quit.
When it was initially written, it was rushed in, and the first thing that got crossed out from the list was IPv6 support. And fortunately for the schedule, it turned out some bits and pieces of another feature could be reused here and there.
The end result was a massive 30,000-line... thing, that not even its creator really understood by the time he was done. A good chunk of that code was there to glue the bits that could be "reused" to the new feature. There was no abstraction layer -- when IPv6 support had to be added in, what happened was another massive dump of maybe 10,000 lines, that was interleaved with the other one via a thick forest of if-this-is-ipv4-do-ipv4-stuff-else-do-ipv6-stuff.
After humongous amounts of testing and bugfixing, it actually made its way out through the door. which effectively marked it as "too expensive to rewrite", and that was it.
Unlike the thing at #1, there was no way to extend it, in any way. Adding even the tiniest feature took weeks and spawned dozens of bugs. Unlike the thing at #2, this wasn't some internal tool, it was production code.
Truth is, it works, or at least it worked the last time I had anything to do with it. But in terms of investment it was a really bad thing to do. It was so hard to extend that there was no way to accommodate customer requirements in any sort of realistic timeframe. Keeping up with the competition basically required two engineers working full-time, on something that wasn't necessarily a critical feature but you couldn't not have it.
This turd probably removed way more value than it added. Or, if not, it certainly prevented way more value from being added. It's my standard for turds.
Yes, that’s “value” in an important sense. But people rarely add in the opportunity cost.
We make decisions every week about what can be done based on the tech debt involved. Every time we punt on an improvement, that’s a real cost. These boondoggles that forever wall off parts of the product as immutable have a cost week after week. What’s the net value after you subtract that cost? Is there any?
I meant it more like a recollection than a lamentation, but it was cathartic here and there :-).
I don't know if it's obvious from it, so I'd rather spell it out -- there are times when "turds" are useful and not to be disdained, much like their real-word cousins: cow dung can be a good construction material and a useful fuel. Certainly worse than concrete and uranium but if that's all you can find or all you can afford, it sure beats eating raw meat and sleeping under the stars.
This isn't true of every piece of software shit in existence, though. Sometimes, "but it works" is just a bad excuse.
Yeah, I guess like most things that's true to a degree. But, those turds have a way of coming back to haunt a project in the form of technical debt.
It would really be interesting if you could calculate how much the technical debt ends up costing on the average project, and whether it's worth the savings gained from leaving the turds in place.
That's an excellent question. It depends, to some extent, on the question if a solution with less technical debt would've been possible at all.
Often, the "turds" were either the only thing possible at the time, or the savings there opened up other opportunities. Not always - sometimes the "cost savers" simply insist on digging a grave for the project.
But that's the main distinction - if it's bad and yet lives on, there has to be value in it. No company spends money on something that doesn't provide value. I suppose what you are arguing is that the product doesn't necessarily provide the maximum value possible. But that's a pretty high bar to meet.
There's always a "good enough". In a perfect world, engineering and product "good enough" coincide. If only one is good enough, you get either a badly engineered financial success, or a financially disastrous monument to engineering.
All other things being equal, only the former lives on. And hence, "turds live on" - and make money, and pay paychecks. And if their maintenance costs exceed their revenue, they usually get shut down.
(I'm deliberately ignoring all projects that can afford to ignore money. The rules are different there.)
Plenty of companies spend money on things that provide no value - which is why msrketing is a thing.
I’ve sometimes wondered - not entirely ironically - if development teams would be understood as a revenue source instead of a cost if they hired their own micro-marketing sub-team to do internal marketing to management.
And that's OK, because we're in the business of providing value, not building shiny monuments to our incredible cleverness.