Hacker News new | ask | show | jobs
by Jtsummers 1620 days ago
> Shitty code is almost always unmaintainable. (Unless the shittyness is local inside small functions, but I doubt that's acommon case.) Of course over-engineering and needless optimizations also lead to unmaintainable code.

I was going to write something similar, so piggybacking. The shittiest code I've seen has always suffered from this.

Sometimes it was shitty (in this sense) because of an assumption that it was "throwaway" code, but it was never thrown away. Gross copy/paste throughout, highly redundant code (same variable, or variable with the same intent, created in many local blocks), mostly existing in mega functions (thousands of lines long) with complex conditional logic to navigate to specific desired sections from the entry point at the top. If it was really throwaway code, then this can be tolerated. But it doesn't require much thinking into the future to replace a 10-line block that's repeated 50 times with one change at each location into a single function. If, in the future, some of those 50 uses of the function need a different function, change it then. Better that than having to keep 50 locations in sync with each other because "making a function now is premature optimization" or "YAGNI!!!". Well, programmer time and delivering quickly has value too. When what would have been a 5-minute task (read function, change function, rebuild, rerun) becomes a 5-hour, 5-day, or 5-week task then everyone is losing out because of the shittyness that was trivially observable and correctable early on.

The other big example of shitty code that is unmaintainable (or becomes unmaintainable) is tight integration between IO and business logic. Without a clean separation, you typically end up with similar repetition to what I described above, or something where a "small" change ends up having massive knock-on effects. This brings maintenance to a crawl as you have to tease out the consequences of that small change, which is non-trivial. That's what makes the code shitty. Corrections and clean separation are often forestalled for the same reason that the previous example often ends up with a mega function instead of a nice, often small, set of utility functions: YAGNI. If your project is going to last more than a few months and has even a modest level of complexity, you will need that clean separation. Otherwise, you end up with increasingly complex (but unnecessarily) code that works around the initial self-inflected hamstringing, or you waste weeks or months cleaning it up and delivering nothing to customers, who become impatient so the cleanup gets cut short and you now have a hybrid mess: half-good code (that will decay rapidly) and half-shitty code (that still can't be maintained).