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.