If there’s one lesson I hope to get across in Tidy Together it is this—software is grown, not made.
When someone says, “Functions should be X-ish lines long,” they miss this fundamental truth. Regardless of how long functions start out, they’re going to grow. That growth is subject to natural laws, chief of which is, “The long get longer.”
Picking a number of lines ignores how functions actually grow. The question is not, “How long should functions be?”, it’s, “What is the distribution of function length?” Turning to data…
Thanks to this week’s sponsor, Screenshot Bot. Arnold Noronha, the founder, was a student of mine at Facebook.
Screenshot tests for mobile apps (and more)
Want to know when something has accidentally changed in your mobile app? Screenshot tests occupy a unique point in the space of tests—easy to write, predictive, & automated.
Use https://screenshotbot.io/tidyfirst to signup to get 20% off your first year.
JUnit 5 Lines/Function: Power Law Analysis
I chose JUnit 5 as my experimental subject, not for any particular reason except that I used to know the code well (turns out I don’t any more). I hope you’ll replicate the results below with your own code bases (especially if your results contradict mine—please LMK). Here is the distribution of lines/function:
1 line—1436 functions.
2—5491
3—1773
4—1163
…
74—1
Once I had the raw data, I fed it into isitapowerlaw.com. What follows is what came out.
Distribution Statistics
Total Observations: 12,513
Power Law Exponent (α): 2.46
R-squared: 0.9600
Range: 1 - 74
Mean Value: 3.49
Power Law Interpretation
The data shows strong evidence for a power law distribution with exponent α ≈ 2.46. The high R² value (0.96) indicates the log-log plot is very close to linear, which is a key signature of power law behavior.
This type of distribution commonly appears in natural and human systems where there are "rich get richer" dynamics, scale-free networks, or self-organized criticality.
It’s a Power Law
The log-log plot of the CCDF (Complementary Cumulative Distribution Function) shows a strong linear relationship (R² = 0.96), which is characteristic of power law distributions.
The estimated power law exponent α ≈ 2.46 falls within the typical range (2-3) observed in many real-world phenomena. This suggests the underlying process exhibits scale-free behavior where extreme events, while rare, occur more frequently than would be expected in a normal distribution.
Implications
So, how long should functions be? Since it’s a power law distribution, the Central Limit Theorem doesn’t apply. The mean is going to increase the more samples we see. Put more plainly, the bigger the project, the bigger the average length.
How long, then? Lots of a short functions. A few long ones. The longest long one will keep getting bigger the more functions there are in the system.
Even though we can’t control whether or not function length follows a power law distribution, we can influence the slope of the distribution (the alpha mentioned in the analysis). Making the slope steeper means many more short functions & much reduced length of the longest functions.
What causes the slope to get steeper? The only empirical result I’ve seen is Keith Braithwaite’s study showing that developing with TDD is correlated with a steeper slope. If you find other ways to increase the slope, or other correlations, please LMK.
Kent, you solved this one last century in your Best Smalltalk Pattern Practices book. Apologies if I mangled the title. One function per intention. It puts the spotlight on the real question: the granularity of intentions. Or, in L Peter Deutsch language, the granularity of the invariants in that part of the program.
I wonder how function length compares to “popularity” of the function at runtime. My experience is those 74 line monsters are doing a lot of work and are often crucial to the critical path. In fact the complexity is what often defies refactoring into better more succinct steps.