----------------------------- Avoiding deep indentation in code ----------------------------- -Ian! D. Allen - idallen@idallen.ca This file deals with when you might violate structured programming principles to make your code less indented and easier to read and modify. My preference is to avoid deeply-nested code. It is hard to follow, doesn't print well on paper, and it's hard to read on the screen. http://safari.oreilly.com/0735619670/ch19lev1sec4 "Excessive indentation, or "nesting," has been pilloried in computing literature for 25 years and is still one of the chief culprits in confusing code. Studies by Noam Chomsky and Gerald Weinberg suggest that few people can understand more than three levels of nested ifs (Yourdon 1986a), and many researchers recommend avoiding nesting to more than three or four levels (Myers 1976, Marca 1981, and Ledgard and Tauer 1987a). Deep nesting works against what Chapter 5, "Design in Construction," describes as Software's Primary Technical Imperative: Managing Complexity. That is reason enough to avoid deep nesting" -------------------------------------- Deep nesting in structured programming -------------------------------------- Sometimes you want to select one of several alternatives in a loop. Here is some typical deeply-nested IF/ELSE code found in structured programming: while( something... ){ if( test1... ){ code1... } else { if( test2... ){ code2... } else { if( test3... ){ code3... } else { if( test4... ){ code4... } else { if( test5... ){ code5... } else { if( test6... ){ code6... } else { code7... } } } } } } } From the point of view of structured programming, the above 27 lines of code are good because they have one entry point (the top of the loop) and one exit point (the bottom of the loop). However, the code is hard to read and hard to modify. To add, delete, or re-order an IF clause requires changing the indentation of all the other nested IF clauses. Even though one alternative is pretty much of the same importance as any other, the lower alternatives each have to be indented to fit the IF/ELSE structure. The deeply indented code doesn't look like it's selecting one alternative from a list. Some relief from the deep indentation problems can be had by removing one redundant set of braces on each ELSE: while( something... ){ if( test1... ){ code1... } else if( test2... ){ code2... } else if( test3... ){ code3... } else if( test4... ){ code4... } else if( test5... ){ code5... } else if( test6... ){ code6... } else { code7... } } The above structured code is only 17 lines - a big improvement over the original 27-line version; but, the chained list of IF/ELIF tests still tangles together overall meaning of the code block, which is to do exactly *one* of the given alternatives in each loop iteration. Above, at least the re-ordering, adding, or deleting of IF clauses is easier than before; since, the indentation level is now more consistent. It's still a minor pain to swap the order of the first test (test1/code1) or the last test (code7) with any of the other alternatives. ----------------------------------------------------- Multiple continue points reduce need for deep nesting ----------------------------------------------------- Here is another version of the same code that produces the same output, without the deep nesting, and without the need to link the entire block of code together using ELSE/IF: while( something... ){ if( test1... ){ code1... continue; } if( test2... ){ code2... continue; } if( test3... ){ code3... continue; } if( test4... ){ code4... continue; } if( test5... ){ code5... continue; } if( test6... ){ code6... continue; } code7... } The above code is not good "structured programming", since the code has multiple loop continue points, not just one. However, the code is no longer than the original example, easy to modify, and easy to read. You can add, modify, re-order, or delete IF clauses without changing any indentation. No "else" clauses are needed, since each IF clause simply "continue"s back to the top of the loop. As before, exactly one of the cases is executed in each loop iteration; but, each alternative is its own independent code block and the code is easier to read. The structure is similar to a switch() statement. Both the structured and unstructured versions of this code are correct; both get you full marks. My preference is for code that is easy to read, understand, and modify, even if the code violates "structured programming" rules. Deeply indented code is unreadable; fix it. See also (deep nesting shell programming example): http://teaching.idallen.com/cst8129/05f/notes/deep_nesting.txt "Less code is better code."