Small Functions considered Harmful

Supposed benefits of smaller functions

A number of reasons usually get wheeled out to prove the merit behind smaller functions.

Do one thing

The idea is simple — a function should only ever do one thing and do it well. On the face of it, this sounds like an extremely sound idea, in tune, even, with the Unix philosophy.

The fallacy of DRY

DRY and a propensity to make functions as small as possible aren’t necessarily the same thing, but I’ve observed that the latter does many a time lead to the former. DRY, in my opinion, is a good guiding principle, but an awful lot of times, pragmatism and reason are sacrificed at the altar of a dogmatic adherence to DRY, especially by programmers of the Rails persuasion.

The name of the game

Speaking of abstraction, once it’s decided what to abstract and how, it’s important to give it a name.

Loss of Locality

Small functions work best when we don’t have to jump across file or package boundaries to find the definition of a function. The book Clean Code proposes something called The Stepdown Rule to this end.

Class pollution

Smaller functions also lead to either larger classes or just more number of classes in languages that support Object Oriented Programming. In the case of a language like Go, I’ve seen this tendency lead to larger interfaces (combined with the double whammy of interface pollution) or a large number of tiny packages.

Fewer Arguments

Proponents of smaller functions also almost invariably tend to champion that fewer arguments be passed to the function.

Hard to Read

This has already been stated before but it bears reiterating — an explosion of small functions, especially one line functions, makes the codebase inordinately harder to read. This especially hurts those for whom the code should’ve been optimized for in the first place — newcomers.

Shallow Modules and Classitis

One of the most powerful ideas proposed in the book A Philosophy of Software Design (which was published subsequent to the initial publication of this post) is that of deep and shallow modules.

When do smaller functions actually make sense

All things considered, I do believe small functions absolutely have their utility, especially when it comes to testing.

Network I/O

This isn’t a post on how to best write functional, integration and unit tests for a vast number of services. However, when it comes to unit tests, the way network I/O is tested is by, well, not actually testing it.

Property based testing

For something that can provide such an enormous amount of benefit with such little code, property based testing is woefully underused. Pioneered by the Haskell library QuickCheck and gaining adoption in other languages like Scala (ScalaCheck) and Python (Hypothesis), property based testing allows one to generate a large number of inputs that match some specification to a given test and assert that the test passes for each and every one of these cases.

Conclusion

This post’s intention was neither to argue that DRY nor small functions are inherently bad (even if the title disingenuously suggested so). Only that they aren’t inherently good either.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Cindy Sridharan

Cindy Sridharan

10.9K Followers

@copyconstruct on Twitter. views expressed on this blog are solely mine, not those of present or past employers.