Pinderkent

Pain and glory from the trenches of the IT world.

The role of nesting in limiting the size and complexity of functions and methods.

Posted on Wednesday, March 11, 2009 at 1:53 AM.

I read an article today that discussed the optimal size of methods or functions. The article references a number of books and academic studies regarding this topic. As with most things, it appears that what's needed is a healthy balance. In this case, it's a matter of distributing complexity in a way that makes the entire application more understandable and easier to work with, while at the same time not making individual methods of functions too complex.

I've worked with a number of codebases over the years that have taken very different approaches to problems such as these. Some have set a very strict limit on the size of functions or methods, in terms of lines of code. Others have exhibited much more flexibility.

All in all, I think that strict lines-of-code limits typically aren't beneficial. When using an OO language, this often translates into classes with a large number of small private methods. While each method may be less than, say, 25 lines of code, the class as a whole isn't necessarily easier to understand or worth with. Following the flow of execution soon becomes an act of skipping between these small methods. In many cases we find that 10 methods of 20 lines each can be more difficult to follow than one method of 200 lines.

It doesn't help that many mainstream languages don't allow for nested functions. When using a language like Java, for instance, we often run into cases where we have a large method that we want to separate out into smaller methods, but our only choice is really to create one or more private methods in the same class. If the class consists of several such methods that we'd like to break up, then things can become more awkward as we have a proliferation of private methods that are really only used by one other method. Ideally, we could define functions or methods that are defined within the "parent" method. This doesn't reduce the overall size of that method, but it does allow for it to be broken up into smaller pieces of logic.

Noted C++ export Herb Sutter gives some examples of how to simulate nested functions using C++. I found another article showing a technique using C# delegates. Arguably, these techniques make the code more difficult to follow. GCC's extension allowing for nested C functions is somewhat cleaner, but at the cost of portability.

One benefit of using a functional programming language is that most allow for, if they don't outright encourage, the use of nested functions. The Standard ML of New Jersey homepage specifically mentions this as a benefit of Standard ML in its summary of the language, for instance. Some examples can be seen within the 'Merge Sort' section of the Wikipedia article on Standard ML. Functions exist within the context where they are most needed and most useful, but otherwise remain out of the way.

A good rule of thumb might be to make methods or functions just as long as they need to be to complete one task, and to do that task well. Immutability, which is core to functional programming, also helps encourage this sort of coding. We end up writing short, local functions that return values rather quickly, rather than writing longer functions or methods that manipulate state stored in global variables or class member variables. So in the end, it may come down to using a language or at least a language implementation that allows for nested functions or methods. If that's not a possibility, there are workarounds to simulate such functionality while using languages like Java and C++. And if that's not a possibility, then it may just be best to have slightly longer methods.

Permalink: http://pinderkent.phumblog.com/post/2009/03/the_role_of_nesting_in_limiting_the_size_and_complexity_of_functions_and_methods
Share:
Feeds
  • RSS 2.0 Feed
  • Atom 2.0 Feed
Tags
Archives