If we think of programming as writing, the best analogy to a paragraph is a function. In good writing, a paragraph should be clear, focused and propel the argument forward. Similarly, in programming, a function should do one thing and only one thing. A function that reads in a list and sorts it does too much: it should be broken up into two functions, one that does the reading and the other that does the sorting. Later, when we discuss documentation, you'll learn that each function should be preceded by a paragraph describing its use and purpose. If you ever feel tempted to use two or more paragraphs in that description, the function is definitely too long.
This rule can be confusing: what counts as ``one thing?'' If a function finds the smallest element in a list is that one thing? If it finds the smallest element and swaps it with the first element, is that one thing? If it repeatedly swaps the next element with the smallest element in the rest of the list, is that one thing? We call the last algorithm ``selection sort,'' so it seems like one thing.
In fact, any of the preceding is acceptable modularity, as long as the function is properly named. Just as some paragraphs are short and others long, some functions are short and do very little, while others are longer and accomplish a lot. You would prefer the smaller functions if they could be called independently, thereby providing a general service, like our swap function above. If the smaller parts are useless and the single function doesn't become excessively long, you would prefer the larger function.
What is the proper size of a function? Is there a minimum or maximum number of lines in a function? No, no firm limits can be set, but I can give general guidelines. The most important is determined by the size of the screen: it's annoying to have to scroll back and forth to read a function; it's nice to be able to put all the lines of a function on the screen at once. I would use that limit for any programmer; beginners, however, should aim for shorter functions. Just as beginning writers use shorter sentences with simpler structure, beginning programmers are writing smaller, shorter programs with smaller, shorter functions. I would advise sophomores to avoid writing functions that are longer than two dozen lines. Juniors and seniors can go longer, particularly if the function is conceptually simple.
Please take the guideline in the previous paragraph with a pinch of salt: some short functions are very conceptually complex, while some long functions are conceptually simple:
In the second code segment, I could go on for two dozen more lines of formatting and output, and never run the slightest risk of confusing anyone. The code on the top, however, is only three lines long and shows C at its nightmarish zenith of expressive power. I wouldn't wish five consecutive lines of that kind of stuff on anyone. All lines are not created equal.// Like strncmp, except it ignores case in the comparison. int strncmp_ic(char *s, char *t, int n) { int diff; while( 0 == (diff=toupper(*s++)-toupper(*t++)) & (n--)) ; return(diff); }void print_info(char *name, char *address, char *phone) { cout << endl << ``name = `` << name << endl << ``address = `` << address << endl << ``phone = `` << phone << endl; }
When writing a function, we sometimes see that it has conceptually distinct phases or parts. When that happens, it is acceptable, even helpful, to put a blank line between these phases. Even better is a blank line followed by a documentation line that explains what is in store in the next phase. This helps the reader see the sub-structure of the function. However, note that one blank line is sufficient. There is never any reason for two consecutive blank lines within a function, and rarely even in a file. Remember that is is useful to be able to see lots of the code on the screen, so keep it relatively compact.