3 ms·
Relevant recent discussion: • https://news.ycombinator.com/item?id=18959636 https://news.ycombinator.com/item?id=18959636 (John Carmack on Inlined Code (2014))
by svat 8y ago
Relevant recent discussion:
• https://news.ycombinator.com/item?id=18959636 https://news.ycombinator.com/item?id=18959636 (John Carmack on Inlined Code (2014))
• This comment, which contains a useful example: https://news.ycombinator.com/item?id=18832382 https://news.ycombinator.com/item?id=18832382
Please let me know of any further discussion on the topic. (I'm also reminded of Ousterhout's advice in A Philosophy of Software Design that “classes should be ‘thick’” — see talk https://www.youtube.com/watch?v=bmSAYlu0NcY https://www.youtube.com/watch?v=bmSAYlu0NcY or (unrelated) slides: https://platformlab.stanford.edu/Seminar%20Talks/retreat-2017/John%20Ousterhout.pdf https://platformlab.stanford.edu/Seminar%20Talks/retreat-201... )
One thing I see people miss in this discussion is that there's a tradeoff between having an individual function be understandable (shorter functions are easier to understand) having the entire codebase or interrelationships between functions be easier to understand (fewer functions are easier to understand). When there's an example presented like in the post, it's often presented as an example with a single function, and of course four short functions may each be easier to understand than a single function, but you've also added three nodes to the “graph” (of functions and calls between them) and now you need to study whether these functions are called from anywhere. To make up for this one may start introducing classes/objects to indicate “private”/“public” functions, and so on. (Some languages allow nested functions, which can help.)
Most of all I'd say reading very different styles of code, and seeing how people achieve great things in unusual ways (e.g. with lots of abstraction, or with very little abstraction), can be an illuminating experience (see my comment in this thread about reading Knuth's programs).
- svat 8y agoTo elaborate more on the idea that splitting up functions introduces complexity at the level above functions: Conventionally, programming languages provide only a few levels of abstraction. For example, if a bunch of related lines of code are logically related and can be understood as a unit, one may group them into a function. If a bunch of related functions make sense as a unit, one may group them into a class. If a bunch of classes make sense as a unit, one may group them into… a file, say. (If the language allows it: some languages allow only class per file.) And if a bunch of files make sense together, one may group them into a directory. After that, I guess directories can be grouped together for a few levels; beyond that one may group them into separate packages / modules or programs / microservices / what-have-you. These different levels of grouping feel different (one tends to have a different reaction on seeing a bunch of microservices than on seeing a bunch of functions). There are probably tendencies to avoid much grouping of certain kinds and have groupings of the kinds that an individual programmer/team likes. What we really want though, is from the other direction (top-down, not bottom-up): we want to start with the system we care about, have it broken down into “not too many” parts (whatever that means: 3 is probably fine, 50 is probably too many), then have each part broken down into not too many parts and so on. When you break up a function that does A,B,C,D,E into separate ones, you may be introducing abstraction for the sub-parts, but you're losing the abstraction you had at the higher level (that A,B,C,D,E are in some sense one unit) and have to now make up for it in some other way: that's (part of) the cost. (Aside: WEB/CWEB-style “literate programming” provides one way to have grouping that, by being infinitely nestable, is self-similar: you can have the same kind of grouping at many different levels, and you can organize these however you prefer: e.g. group related sections into a “chapter”, chapters into a “part”, then break the entire “book“ if it's too long (though I don't think anyone's done that) into separate “volumes”, or whatever kind of grouping you like. And now you can have less of the language-level abstraction, e.g. an entire chapter may tangle into a single 1000-line function, which now is likely to means something more—that it's called from several places, for example—than merely being the way of achieving grouping.)
- dahart 8y agoYou might like this related comment https://news.ycombinator.com/item?id=13571159 https://news.ycombinator.com/item?id=13571159
- svat 8y agoThanks for sharing; that's an interesting discussion.