3 ms·
I see it as a tradeoff of where you want your dependencies. In analysis using the structured program theorem, you only have three tools, really: Sequence, sele
by megameter 6y ago
I see it as a tradeoff of where you want your dependencies.
In analysis using the structured program theorem, you only have three tools, really: Sequence, selection, iteration. If you copy-paste, you lean on the sequence more; if you add a loop or a cursor structure, you're iterating; and if you add more names for things, you're selecting on the name. All three create dependency risks, but not in equal measure.
What a really long function mostly indicates is that the inherent dependencies are mostly sequential. This maps with the domains where they appear most naturally: game loops are notoriously single-threaded, embedded code often needs to operate to hard real time constraints.
I think the appeal in splitting out more names has something to do with linguistic comfort zones: Rather than examine long sequences, assume the functions used by the one you are looking at are trustworthy. Then you are "improving" the code each time you factor it out because you can read more names, and because each function is small there is little concern about sequencing errors. It's intuitive, but shows its flaws as soon as you use another lens like the structured program analysis; adding the new function makes it harder to examine the sequence across the function boundaries, causing the "flea-jump" code you describe.
What I've found works is to let the large functions accumulate and mature, then derive a new dependency - a function, class, or other abstraction - that will simplify maintenance. Not every problem is solved with a new function, sometimes it really takes a compiler to get the desired improvement.