How Big Should a Function Be? 28

Posted by Uncle Bob Tue, 30 Oct 2007 03:25:37 GMT

In the ‘80s we had a rule that a function should be no longer than a screenful. Few, if any, of us followed that rule. Our functions were typically much longer than the 20 lines that would fit on a VT100.

Nowadays, on a 17” laptop screen with the font cranked way down low, you can get 60, 80, maybe even 100 lines of code on the screen. Does the same rule still apply? Should functions be no longer than a screenful?

Of course the idea is ridiculous. Functions should be small. Very small. A well written function might be 4, 5, perhaps 8 lines long; but no longer.

There are exceptions of course. Some functions will have long switch/case statements (We’ll talk about those later), or long array initializations, or some other mindless structure that simply takes space to fill. But the fast majority of functions are not of that kind, and should be very short. Specifically, functions that process information as part of an algorithm should be very small.

A function should have zero or one level of indentation. Nested ifs and while’s should be avoided in most cases. Moreover, the body of an if or while should be one or two lines long. Typically, the body of an if or while statement should be no more than a single function call.

The body of a try block should also be a function call; and the word try should be the first word in the function.

Each function should have a descriptive name, two or three words in length, that makes it clear what the function does. Moreover the function should have between zero and three arguments.

A source file should read like a newspaper article. Newspaper articles begin with a headline, followed by a single synoptic paragraph, followed by paragraphs full of ever increasing detail. The ideal article can be read until it gets boring. A source file should read the same way. High level functions should be followed by lower level functions that should be followed by still lower level functions. The calls should all point downwards in the source file if possible.

Of course these rules cannot be followed 100% of the time, but they are good rules nonetheless. Our goal, as programmers, is to write programs that humans can understand and maintain.

It is not good enough that a program work. A program must also be written well. As a programmer you should take pride in your work and never leave a mess under the hood. Remember, a product that works, but that has a bad internal structure is a bad product.

Comments

Leave a response

  1. Avatar
    Jan Daniel Andersen about 7 hours later:

    YES!!!

    Even though most of us know this to be true and practice these rules everyday, it cannot be said often enough. Even those of us, that are very thorough about making our code nice, needs to hear this once in a while.

    Readability is (or should be) on the very top of the checklist, you go through before declaring you code done (done done). Ofcourse the application should work, but I’d much rather fix a well written application with errors than maintaining a working app, with ugly code.

    No code comments (apologies), no long functions, no intricate nested conditionals, no “And” in methods names… no no no! Only code devided into small comprehensive bits of functionality, with names that make it’s purpose totally obvious (even your mom should be able to get the overall idea of what the code does). When a software professional sees wellwritten code, he/she smiles with enjoyment.

    As professional software people we don’t produce applications or systems. We produce (as a team) the working instructions (sourcecode) that lets the compiler build the application or system. And those working instructions needs to be understabdable by the people working on them. Forget that and all is lost.

  2. Avatar
    Peter Wood about 9 hours later:

    That’s the first time I’ve seen anyone suggest putting ‘try’ in the name of the function, although I have done it myself in the past. I wasn’t sure what it was communicating though. Does it just mean the function could throw an exception? Should that function not be used without a try block?

    I like increasing the font size so that I can’t fit more than 80 characters on a row. That helps with function length too.

    Obviously, functions shouldn’t be TallerThanMe, although I’m quite tall.

  3. Avatar
    Brandon about 11 hours later:
    A source file should read like a newspaper article.
    A fun exercise that I do occasionally on my Mac is to highlight a method in your source code and run text to speech on it. If the T2S engine gets confused then you could probably stand to clean up the code a bit.
  4. Avatar
    Anonymous@spambob.com about 12 hours later:

    The body of a finally block should also be a function, preferably callded ‘cleanup’.

  5. Avatar
    Nathan Henkel about 13 hours later:

    An interesting effect of applying the “many short methods per class” rule is that, on modern displays, and entire class definition will occupy about a screenful. That’s a really good thing.

    Of course, that goes away if you require a header for each method or have some other comment-intensive requirement. Comments, which are supposed to illuminate the code, actually obscure it when they force the reader to scroll to find a method that could be on the same page. This is yet another reason to use comments sparingly and instead make the code speak for itself.

  6. Avatar
    yachris2112 about 14 hours later:

    Doesn’t this just raise the question of how many methods a class should have?

  7. Avatar
    Rafael de F. Ferreira about 16 hours later:

    Great advice, but the following let me intrigued: “The body of a try block should also be a function call; and the word try should be the first word in the function.”

    I would love to see an example of code following this guideline.

  8. Avatar
    Dmitry Pavlov 1 day later:

    Good advices. But in practice, we often need to use external framework and it is impossible for some of them to write something useful in few lines. As an example – Managed Package Framework (MPF) from Visual Studio SDK.

  9. Avatar
    Clint Shank 1 day later:

    I wholeheartedly agree and have written about this topic here.

    The interesting part comes after you’ve created all these small methods. You look for where you can move them. That is, you ask, “does this behavior really belong somewhere else?” In object-oriented programming, typically, you can pull up to a base class, extract a new class (e.g., you realize a Data Clump) and move the method over, move the method to one of the objects passed in as a parameter, or maybe even move the method to a utility class. Writing small methods makes this identification easier.

  10. Avatar
    Ruivaldo 1 day later:

    Great hints. I always do this in my code, but i felt sometimes that i was one of the few that does. ;) I was feeling alone, thanks :P

  11. Avatar
    GregB 1 day later:

    Wouldn’t the size of a function be dependent upon what language it is written in? One can accomplish a lot of mayhem with four or five lines of Perl. With four or five lines of well-crafted APL, one can take over the world.

  12. Avatar
    www.EdmundKirwan.com 1 day later:

    Strange, I was just thinking about this a couple of weeks ago.

    I don’t know how big a function should be but splitting functions into smaller functions within a class (if I can go OO for a moment) does have the interesting side-effect of increasing the potential structural complexity of your system, and even defining how big the encapsulating classes should be.

    Well, theoretically, anyway.

    You’re welcome to some thoughts on how big classes and name spaces should be, here: http://www.edmundkirwan.com/encap/intro.html

    .ed

  13. Avatar
    Stan 2 days later:

    I opened a source file the other day and found a 5,000 line method with all local variables defined at the top. I cried a while and went home early. My granddaughter deserves my time more than this. :-)

  14. Avatar
    JamesH 2 days later:

    Length only matters if you’re mixing concepts. For example: if you’re effectively entering data in code(like some patterns for shapes, or variable initializations) then additional subroutines will only add confusion. And if you’re implementing a complex algorithm, you will probably have to code it in a complex way as well. But if you’re doing different things at different points, then adding functions for each, or at the minimum comments, will serve you well.

    Horror 1000+ line functions are usually ones that ignore reusability in favor of cut, paste, tinker methods.

  15. Avatar
    Length and Depth too 3 days later:

    A fellow once said that a “simple” function with “only” ten booleans would be impossible to test exhaustively (like that was a goal) due to the sheer number of combinations. I would like to see a 10-line function handle ten independent boolean conditions. Or rather, I would hate to see ANY function deal with 10 independent flags.

    In other words, a small function can’t be too intense, deep, or complex. That’s why we like them small.

  16. Avatar
    Dave G 3 days later:

    Uncle Bob, is there any production code written by you that’s available for public view? I’d like to see how closely you follow your own rules.

  17. Avatar
    Nathan Henkel 3 days later:

    I believe all the source code for Fitnesse (http://fitnesse.org) is available for download.

  18. Avatar
    p2r 4 days later:

    This is GREAT advice. But … it is possible to take this approach too far – there is a balance between small methods and number of methods (and classes and packages). I am not saying that you shouldn’t write small functions, I am merely saying that it is possible to overdo it. I’ve done it, and my fellow developers complained – it was very hard to understand what was going on since the code was scattered over a zillion one-line methods. This perhaps just as bad as having all the code in one function – in neither case you can understand what’s going on.

  19. Avatar
    Dave G 4 days later:

    I just looked at the fitnesse source, and he violates those rules all over the place, even where the so-called “exceptions” don’t apply. So, in other words, one should write short functions where short functions are called for, but longer functions where longer functions are called for.

    What sage wisdom.

  20. Avatar
    Nathan Henkel 5 days later:

    @Dave

    Uh, could you be more specific? I skimmed some of the code, and the longest method I found in my skimming was 14 sloc. Most were around 8 or fewer. I didn’t see a single example of naming a function called inside a try block try*, but I also know some that things I would advise today are not present in code I wrote 6 months, or even a month ago. My technique is constantly evolving.

    Anyway, if you were to provide some specific examples, and ask questions rather than make broad assertions about “violations all over the place” it would REALLY help you look more objective, and less like someone who’s already made up his mind before he even asks the question.

    I honestly don’t even know if the fitnesse source really follows Bob’s stated principles—I just mentioned it because I know it’s production code Bob worked on. I’d be interested to hear an argument on the subject. But probably not from you. You just come off as an axe-grinder.

  21. Avatar
    xinghua hu 8 days later:

    I agree with GregB. I think the functions of C++ may be long than java’s.Because i think that modifiy C++ function is more difficult. I must change the declare, define and invoker.And they are always in different files.So when I write C++ program i always make flew functions.

  22. Avatar
    hu 8 days later:

    I agree with GregB. I think the functions of C++ may be long than java’s.Because i think that modifiy C++ function is more difficult. I must change the declare, define and invoker.And they are always in different files.So when I write C++ program i always make flew functions.

  23. Avatar
    The Unknown 8 days later:

    One of these nice posts that have a huge amount of “should” in it, but not one single “because”. Hey, I can do this too: You are wrong, anything should be the other way around.

    Seriously, a nice list of thumb rules, but missing any context and therefore quite worthless.

  24. Avatar
    Nathan Henkel 9 days later:

    @The Unknown

    are you claiming the following? 1) It’s a nice list of rules of thumb 2) It has no context 3) Lack of context makes a thing useless

    I think we can also allow this definition 1) All rules of thumb exist without context (it wouldn’t be a rule of thumb otherwise).

    Consequently, all rules of thumb are useless? That’s a strange thing to say/think.

    Seriously, I think you could say of this post “hey, this has been said before—nothing new here”, but…

    really? you don’t live by any rules of thumb? all your rules are completely context sensitive? how do you keep them all in your head? how do you deal with new situations?

  25. Avatar
    The Unknown 9 days later:

    Nathan,

    as others have mentioned, there’s not even a language given.

    A useful rule of thumb would be “Look left and right when you cross the street.” Mind the context: When you cross the street. Usually you won’t look left and right when you go from your living room into your kitchen—except when you have to cross a street for it ;). The thumb rules in this blog post are more of the kind “You should look left and right.”

    But there is another missing context that makes my example in fact a bit dangerous, because there should be a “or right and left depending on your country.”

  26. Avatar
    Paranoid Android 9 days later:

    All generalizations are false.

  27. Avatar
    Joe Hatfield 11 months later:

    I don’t see why anyone thinks wading through 100 ten line functions would be any better than a single well-commented 1000 line function. It seems like a lot more clutter to me.

  28. Avatar
    Kristian about 1 year later:

    Joe> A program broken into modules is easier to understand, test and modify. Parts can be replaced and mocked as needed. Do you practice unit testing?

Comments