4 ms·
Thank you for these excellent links. This debate often takes the concrete form of “one large imperative function with 100 lines” vs “5 functions with 20 lines”.
by gen220 6y ago
Thank you for these excellent links. This debate often takes the concrete form of “one large imperative function with 100 lines” vs “5 functions with 20 lines”. Many people who separate out logic for the sake of minimizing lines-per-function unfortunately do so by introducing indirection, rather than abstractions, and thereby make the program more challenging to reason about and test. But, the reason the debate is never-ending is because the question isn’t sufficiently defined! :)
I like to think of a program like a tree (main is root, each function is a node, calls are edges). Each sub tree should be a bounded context, in that (ideally) you only have to think about parameters defined in that sub-tree. Leaves implement the “nitty-gritty” (mainly I/O, number-crunching, and complex transformations), and are heavily tested. Each node that isn’t a leaf is either an abstraction composing leaves, or an abstraction composing abstractions. Unit tests for leaves test the nitty gritty, unit tests for non-leaves must only test composition.
I find that human-readable modules have some limits (number of children, height of the tree). You can violate those limits sometimes, but only if you provide some assistance in the form of comments.
Sometimes, a 100-line function is not composing many distinct nitty-gritty ideas. It just really takes 100 lines to express “write this model to the database”.
- MaxBarraclough 6y agoI agree that relatively large functions aren't always an evil. As you say, sometimes there isn't a tidy way to further decompose it. At the same time though I don't think it's always a sin to write a function just for decomposition, without it doing any abstraction. A 'helper function' might be tightly bound to some other function, i.e. the helper function is sensitive to the internal workings of the function it serves, and is not intended to be called from anywhere else. And there's still no excuse for source files that are 5000 lines long, of course. HN discussion of John Carmack's thoughts on how long functions are sometimes preferable: https://news.ycombinator.com/item?id=8374345 https://news.ycombinator.com/item?id=8374345