Not easy to spot side effects if the 5 line function calls 999 other 5 line functions, which you have to do if you replace 1 function with 1000 functions. When people start to arbitrarily break up tightly coupled implementations into tiny functions you will get a much worse mess than if they just kept it as big as it was when they developed it.
Small functions are great, but forcing people to write small functions is not great. They are two different things.
In a programming context:
- If the business process you are trying to model clearly has 20 discrete steps is would be silly break them into 4 groups of 5 steps just to hit the ideal function size.
- Coming up with a good name for an abstraction in a moderately large program can be very tricky, but a poor name is hurting more than helping. Don't split it if you cannot think of a good name.
- If breaking out into a function requires passing in 10 variables then it may become harder to read than simply inlining it. You're probably not abstracting correctly in that case. Etcetera.
I've seen so many over-abstractions from junior programmers trying to be "clean" I wonder if these rules of thumb aren't hurting more than helping.
*) message handlers in raw Win32-apps come to mind
That said, a lot of these huge functions were basically for implementing defined step-by-step processes, and comments delineated the sections as well as loop and condition ends.
That is they should read top to bottom with minimal jumping around and information hiding.
(Of course not in all cases, YMMV, etc)
Over time they all got gradually broken down into smaller functions/methods.
(Disclaimer: I was not the original author of any of these.)
Only from there it becomes possible to have the broad view, reorganize and (re-)factorize the code again properly.
So if I had to choose between both, I'd take the 5000 lines function any time, since it makes my job easier.