Ask HN: Functions: how long is too long?

4 points by blintson ↗ HN
First I was going to ask how long you think a function should be, but there are lots of cases where using short functions is convenient.

Instead I'd like to ask what's the longest you'll let a function get in a given language before you break it up? Why?

I have very little experience coding commercially, but I try and never let any function get >1 screenfull, which is 50 lines for me.

12 comments

[ 3.7 ms ] story [ 38.8 ms ] thread
It is probably too long at 50 lines. Turn the question around, what must the function return and start from there. The function should do no more than necessary to achieve the goal stated as the return of the function.
50 lines is long as I'd ever let it get, not how long I try to make a function. I think hearing from people about why they had to write long functions is like listening to an airplane's black box. It could provide insight on what a language does poorly.
I don't find that it's useful to have any limits on the length of functions; I have code with functions (even main!) are hundreds of lines long.

I do, however, find that it is essential to limit the width of functions, and if my code doesn't comfortably fit into 80 columns when using 8-column tabs, there's a clear sign that it needs to be broken up.

In general, nested loops are far more of a problem than simple "do X, then do Y, then do Z" code.

Interesting! Personally I find that once a function is too long it needs refactoring either into an object or more functions although with web stuff one tends to end up with much longer functions. can we have an example of one of your long functions as to what it does?
can we have an example of one of your long functions as to what it does?

Sure. main() in http://www.freebsd.org/cgi/cvsweb.cgi/src/usr.sbin/portsnap/... is over 400 lines long, and it

* Looks up a server's DNS entries,

* Connects to the server (trying multiple addresses if necessary),

* Constructs HTTP requests and sends them to the server,

* If less than one HTTP request is pending, blocks until it can finish writing a request,

* Reads HTTP response headers,

* Reads an HTTP response body and writes the data to disk,

* Prints a status line,

* if the server sent an HTTP/1.1 response, loops back to the top to continue sending more requests and reading more responses using the same TCP connection,

* and if the connection broke, closes it and loops back to the top to open a new connection and continue downloading.

I separated out the bits which could usefully be put into their own functions (e.g., constructing an HTTP request, or reading a \r\n terminated line from a socket), but there was no point dividing up the rest.

A general rule I hear is screen +~50%. Once you go beyond that, a study I read a while ago (apologies, no links) showed a huge leap in error, they believed stemmed from our difficulty remembering complex / random things. With my own testing, I'd say it fits pretty close. On-screen is pretty limiting, but 2x screen gets harder to be certain about everything in it, all the time. My error ratio is definitely best when I keep my functions below 2x screen height.

That, and once you get into the hundred+ lines of code, you are probably doing something that's more easily summed up as a couple pieces. Using multiple pieces also has the advantage of it being very easy to rapidly change / experiment with your code.

Personally, I tend to restrict functions to 1 screen length. This is not based on any good programming practices list, it's just that I like being able to see the entire function in one view.
Too long is when you need more than once sentence to describe what a function does or when the function name gets too long.

That's a pretty good indicator because it shows that you could 'abstract' something out and make it an individual routine.

Err on the side of caution, better to have smaller functions than larger ones, unless you have a very good reason not to.

And if performance is your worry and you work in 'C' then inline is your friend.

I still aim for the old school

7 +- 2

not including declaratons

If the function starts to feel difficult to work with, then it's too long.
I'm not saying this is right, but at my place of work, our c# coding standard says a maximum of 25 lines. It also says maximum line length of 110 spaces (including 4 character tabs).