Comment by rhubarbtree
12 hours ago
Just chiming in here to say, absolutely you should keep functions small and doing one thing. Any junior reading this should go and read the pragmatic programmer.
Of course a function can be refactored in a wrongheaded way as you’ve suggested, but that’s true of any coding - there is taste.
The ideal of refactoring such a function you describe would be to make it more readable, not less. The whole point of modules is so you don’t have to hold in your head the detail they contain.
Long functions are in general a very bad idea. They don’t fit on a single screen, so to understand them you end up scrolling up and down. It’s hard to follow the state, because more things happen and there is more state as the function needs more parameters and intermediate variables. They’re far more likely to lead to complecting (see Rich Hickey) and intertwining different processes. Most importantly, for an inexperienced dev it increases the chance of a big ball of mud, eg a huge switch statement with inline code rather than a series of higher level abstractions that can be considered in isolation.
I don’t think years worked is an indicator of anything, but I’ve been coding for nearly 40 years FWIW.
> They don’t fit on a single screen, so to understand them you end up scrolling up and down.
Split them up into multiple functions and there is more scrolling, and now also jumping around because the functions could be anywhere.
> It’s hard to follow the state, because more things happen
It's easier to follow state, because state is encapsulated in one function, not constantly passed around to multiple.
> a huge switch statement with inline code
Huge switch statements are a common reason for large functions. Python has this architecture and largely won because the interpreter is surprisingly easy to understand and extend.
> Split them up into multiple functions and there is more scrolling, and now also jumping around because the functions could be anywhere.
No, this is the fundamental misconception used in defense of longer functions.
With a long function, you must scroll no matter what. If you're interested in every detail, you scroll. If you want to figure out the logical steps involved, you scroll (and likely have to take notes as you go). If you want to ignore a step for now, you scroll over it.
With properly factored code, you only jump away when you need to. If you want to figure out the logical steps involved, you just read them off. If you want to ignore a step for now, you just ignore it. If you're interested in every detail, you get to start with an overview, and then you jump around. But caring about details is the exceptional case. Most of the code works most of the time in any sane development practice; when the current code works, the details don't help with understanding the current function.
Jumping around is also not more difficult than scrolling, with a proper editor.
The need for fuctions are usually abstraction or reusability. If you can extract part of the logic under a nice domain concept please do so. It’s better than comments. Not extracting the logic usually means a lot of intermediate variables to keep track for.
If you are passing your whole state around, that usually means, you’ve not designed your state well.