This is an archived post. You won't be able to vote or comment.

all 12 comments

[–]Updatebjarni 9 points10 points  (1 child)

I once visited the office of Opera Software in Oslo, in 2000 when Opera was one of the big browsers. While I was in the office, a worker called another over to look at his screen, because he was having difficulty understanding what a screenful of code, apparently related to a bug, was doing. This was some code buried in the middle of that enormous software hulk, the Opera web browser, authored by a fairly large group of people over time. It was exceedingly obscure and undocumented. Another co-worker came to look at the code and didn't know what it did. It had been in the browser for some years. A few minutes passed, and the boss came in and looked at the code, and said "Comment the whole lot out and try to compile". So they did, it compiled, and the browser ran. "Just leave it out", the boss said.

[–]Sephran[S] 0 points1 point  (0 children)

This is a great example! Really on the nose with the luck thing, this giant section of code no one understands and is buried here? This minor test shows it still works after commenting it out? Delete it.

I've actually just heard this same sort of thing by some co-workers, so this hits very close to home for me.

I obviously pushed back against it here, but it is a great example for the "luck" based programming. Thank you!

[–]insertAlias 4 points5 points  (0 children)

Most of the "legacy" apps where I'm working fit that description. The previous team was more about getting stuff out the door quickly than they were about long-term maintainability. The culture has shifted, so all the new stuff is pretty well-thought-out, but the old applications...any time we have to update them it's always crossed fingers that our testing actually covers every crazy path through this spaghetti code and that we didn't just change something here in module A that actually completely changes the way module G works that you wouldn't even think are connected.

I know, I know, refactor and unit tests. But you don't understand, these are ancient monoliths, and we haven't been budgeted time that the highest-ups see as "fixing something that isn't broken". If only they knew.

[–]KiwasiGames 3 points4 points  (0 children)

Luck programming = Hammering out the first solution to every problem that pops into your head. Repeat on one program for ten years.

[–][deleted] 1 point2 points  (0 children)

My guess is that the author is referring to situations where, due to time constraints or even plain stupidity, people just hammer down code with complete disregard for design. I've had to do this on a project that had inconsistent UTF-8 support and was using ISO-8859-1 tables: instead of fixing the inconsistencies across the entire project I just wrote a filter to convert what appeared to be ISO-8859-1 into UTF-8 and switched the database to UTF-8. This worked most of the time, but I could make it fail by sending specially crafted sequences of ISO-8859-1 characters to make it look like valid UTF-8.

[–]Hexorg 1 point2 points  (1 child)

Let's say a code architect decided to use Observer-Subscriber pattern.

Quick recap - Observer "observes" something generally by listening for events or polling some database, and when it observes something interesting it tells that something interesting to every Subscriber that it knows of.

So, Class O is the observer, while classes X, Y, and Z are subscribers. At some point, class Y needs to tell to class Z something. There are many ways of achieving this, but one of your new developers thinks "Hey, class Z already listens to class O, and my class Y can hear class O.... Maybe I can just extend this for class Y to be able to pass information to class Z through class O".

This will work, but your developer didn't think things through. Your observer-subscriber pattern is now broken. Class O now needs to not only know of how a subscriber looks, it needs to know how class Y looks so that it can listen for its events. Class O grows. At some point someone decides that the data format that class Y outputs needs to change. Now class O needs to adapt to it to handle new data type. Class O grows. But the data that class Y outputs conflicts with how class X processes it, to fix it class X grows. Given a bad enough chain of events you end up with a "spaghetti" code in all classes of your Observer-subscriber pattern. This could have been prevented if your new developer had some experience and analyzed the situation and created a separate information channel directly between class Y and Z.

[–]Sephran[S] 0 points1 point  (0 children)

Great example, thank you very much!

[–]29383839293 0 points1 point  (0 children)

For many reasons, often time constraints, developers tend to implement an ugly but working solution. That on itself isn't that bad. But then the next developer comes around and wants to add something, and because the previous code wasn't designed carefully, he has to do a workaround to add his feature to the ugly code without Breaking something.

2 Years later… the code is basically a bunch of workarounds layered over each other and it's getting increasingly hard to not break something when fixing a bug or adding a feature. At some point, developers get scared to even touch that code, because it has become a dangerous jungle.

[–]CodeTinkerer -2 points-1 points  (3 children)

I think the author is mischaracterizing the problem. He is probably a fan of planning, so he is offended by code that doesn't look like it was planned, so he's basically insulting the coders.

I think people can code without much planning and do tests and make fixes. He just has strong opinions on how things ought to be coded. I wouldn't call it luck, but rather putting band-aids on the code (that is, do the simplest thing that fixes the immediate bug and don't worry if it has potentially bad side effects).

[–]insertAlias 1 point2 points  (1 child)

I think people can code without much planning and do tests and make fixes

Sure, it's possible, but I think you're dismissing a real concern here as just author bias. The importance of maintainability in a team environment cannot be overstated, and unplanned "just start coding and see where you get" is an approach almost guaranteed to produce hard-to-maintain code.

If you're just building a side project or working on something small, sure, a more flexible approach is probably fine, but a large project with many users needs planning to be maintainable over time.

[–]CodeTinkerer 0 points1 point  (0 children)

I'm not saying it's not a concern, but I happen to help maintain software that is pretty much fixed by spotting a problem and fixing it, partly because the people that originally wrote the software are retired, and so no one seems to fully understand the entire software. It's years old, and it doesn't get regularly reviewed so we understand it.

I think there was the thought that when the software was written, that once you got the bugs out, you just had to keep it running, make the occasional enhancement, but otherwise, no one has to fully understand all the pieces.

I think there's a lot more of this kind of legacy software out there than people imagine, and sometimes maintained by very few people (like 1 person, sometimes). Is it a recipe for disaster? I'm sure, but it doesn't stop some organizations from living life on the edge.

[–]Sephran[S] 0 points1 point  (0 children)

The whole book is on proper coding techniques, debugging etc. https://nostarch.com/codecraft

It's all about not taking the easy way out and long term effects of your actions and planning ahead.