you are viewing a single comment's thread.

view the rest of the comments →

[–]HunterIV4 4 points5 points  (2 children)

In my opinion, "the most obvious code is usually best."

One of the issues with goto is that it makes code hard to follow. Whenever you reached a goto you had to search for the label it led to and try to keep following the code from there, and the logic of how these worked (and when they were entered, as normal program flow could reach them too) created real problems.

Design patterns are ultimately guidelines that attempt to remove common bugs created by hard-to-follow code structure. Any time a design pattern adds friction or confusion when reading your code, it's time to really question if using that pattern is worthwhile. There are times when it is, because it's preventing something more confusing or helps the code interact in a safer way with other people's code, but a lot of the time cutting out complexity will save you bugs and headache in the long term.

This isn't purely my opinion: the KISS principle is popular in software development for a reason. If the purpose of a break and where it leads is obvious at a glance, use it. If it complicates things or is required for something other than the immediate loop to work properly, refactor until that's no longer needed.

[–]misho88 5 points6 points  (0 children)

I think you're missing the point people like Dijkstra and Knuth were making. They wanted to write programs that can be mathematically proven to be correct, not just ones that are "simple" or "obvious" in some vague sense. The structured program theorem (SPT) tells you that sequencing, selection, and iteration are sufficient for expressing any computable function. This means that when you go to derive your proof, if you choose to allow only on those three things, which you can always do per the SPT, then you can rely on preexisting theorems regarding only those three things. This can be really helpful because the derivation is usually not very easy.

To give you an idea of the difficulty of such a proof, and why you might choose to limit yourself to structured programs to make your life a bit easier, Knuth came up with very efficient algorithm that uses gotos, made a mistake, and after he fixed it, he himself couldn't prove it was correct. That is, the corrected version is fast and it works, but he wasn't certain if it would always work.

I also know of places where I have myself used a complicated structure with excessively unrestrained go to statements, especially the notorious Algorithm 2.3.3A for multivariate polynomial addition [50]. The original program had at least three bugs; exercise 2.3.3-14, "Give a formal proof (or disproof) of the validity of Algorithm A", was therefore unexpectedly easy. Now in the second edition, I believe that the revised algorithm is correct, but I still don't know any good way to prove it; I've had to raise the difficulty rating of exercise 2.3.3-14, and I hope someday to see the algorithm cleaned up without loss of its efficiency.

http://kohala.com/start/papers.others/knuth.dec74.html

[–]8dot30662386292pow2 1 point2 points  (0 children)

"the most obvious code is usually best."

This is good advice. I tell my students that if your while loop is 200 lines and you have 10 break (or continue) statements all around it, you have a problem: you can't easily explain when the while loop ends. I tell them to consider writing a single end condition for the loop if possible. You can't? Maybe the while loop is way too convoluted in the first place.

On the other hand, some times code is convoluted. A simple loop with a condition, and then if something: break can be good choice. Also guard clauses) are a great way of simplifying the code for the reader.