5 ms·
Martin Fowler of the Agile world, and Garret Smith of the Erlang community, are both excellent programmers whom I respect, and they both take the approach of br
by lliamander 8y ago
Martin Fowler of the Agile world, and Garret Smith of the Erlang community, are both excellent programmers whom I respect, and they both take the approach of breaking code into lots of extremely small functions.
Having tried that style, I notice that I don't particularly favor it, and for the very reason you site: the code is no longer all in one place.
I've switched to moderately sized methods/functions with comments every few lines. Some say that comments like this are a smell, and that you should refactor the commented section of code into it's own function, but honestly comments are easier to read than method names (and again, there's the benefit of locality).
I'll have to take a look at the book.
- war1025 8y agoA technique I use quite a bit is to group functionality within a method using `#{` and `#}` to bound the code doing the thing. It gets you the "grouping" idea of lots of methods, but if the code is only used in one place, there is no reason to pull it out into a method. Something like: #{ Parse input parameters .... <several lines of code here> #}
- spockz 8y agoI like this idea and will try to apply it to our code. Why do you prefer it over splitting the code out in a different method? Is it so you can read everything in one glance? If so, an ‘inline’ feature could be added to IDEs to show definitions inline. Also, when using applicative or Monadic style programming there is little reason not to split things of in small separate functions and chain them together in the right order.
- war1025 8y agoYea, it probably doesn't make sense for every coding style. I just find that if I split things apart too much it turns into spaghetti that I have to try to weave my way through to understand what's going on. There are definitely places where it works out really well though.
- BurningFrog 8y agoI assume everyone who splits code into smaller pieces use modern IDEs that makes it trivial to navigate to functions by clicking them etc. I say this because I'm always astonished by the number of "modern" programmers who refuse to use IDEs.
- m_mueller 8y agoIDE or not, jumping around between functions amd their callers to understand a process is annoying.
- BurningFrog 8y agoSure. In sane code the name of the function should describe what they do well enough that you rarely have to click in to learn how they do it. Or something like that...
- TeMPOraL 8y agoThat applies recursively to the function you're just reading :). I.e. I wouldn't be inside a particular function of a particular module if I didn't have to know something about its implementation. There's a good chance I need to understand all of it at the level of abstraction of the module (often because I'm supposed to change something about it). Making that less painful leads to better and less bug-inducing experience. Elsewhere[0], 'usrusr brings attention to nested functions, lack of which I see as a huge factor contributing to overeager splitting of code. With nested functions, you can have "best of both worlds" - a function whose implementation is divvied up into well-named pieces, while keeping those same pieces in the correct conceptual place, close to where they're used, and restricted from polluting unrelated code. -- [0] - https://news.ycombinator.com/item?id=18773691 https://news.ycombinator.com/item?id=18773691
- m_mueller 8y agoTotally agree on nested functions. I currently have to deal with Java, and those are the biggest thing I miss from Python.
- tonyedgecombe 8y agoIn general I prefer smaller functions. I think the threshold is when they become hard to name. Then I will step back and think about whether it's worthwhile.
- XenophileJKO 8y agoI think it might come with experience. I definately gravitate to very small classses/functions, personally prefering classes to fit within a single screen. Obviously this isn't always achievable. It comes down to: "What do you want to focus on?" Each drill down should be to a lower level of abstraction. It is seperating the what from the how. It results in functions/classes that either detail a flow (set of decisions) or that implement actions. For example I generally don't need to know how to read a file from disk where I am trying to decide if I should read a file. When looking at code you drill down in a very vertical fashion when you want to know "How does it do operation X?" Meaning the operation largely can be understood in isolation. There shouldn't be a lot of context that is required for it. A side-effect is that all the unit tests are very self contained. This utlimately steers you towards a much more functional and compositional programming style. Certainly it is moving complexity around, but the end result is heavy compartmentalization and limiting the context required to understand any section of code.
- cmsj 8y agoI like your description of separating flow from actions, I try to do that too. I want my functions higher up the abstraction stack to read like they are orchestrating black boxes of functionality.