The Trouble With Long Functions

Photo by Riku Lu on Unsplash

 

As a young software developer, I wrote enormous functions. The late 90s was a different time. Bloated functions were the norm more often than I care to recall. Somehow it felt comfortable to shove all the code together. I didn’t know any better—now I do. Today I’ll shed light on why long functions are detrimental to our software.

 

So, what’s the problem with long functions?

 

They are Hard to Understand – Long functions do everything. And that is the issue—they don’t separate responsibilities. High-level policy code is mixed in low-level detail. How are you meant to know what is going on? What is the intent of the function? It won’t be straightforward. A 200-line function might well contain data access code, business logic and presentation logic!

Six levels of indentation and hard to follow conditional branching are not the maintenance developer’s friend. The human brain can only keep about seven items in short-term memory. It’s frustrating and mentally exhausting to try and understand extended functions.

 

They have a Steep Learning Curve – Developers new to the code are going to have a hard time. It can take them a few months until they are comfortable with a codebase containing many large functions. In the meantime, productivity suffers.

Does it have to be like this? What if we inverted our thinking and questioned the long learning curve? Could there be a shortcut to high developer productivity? 

 

They are Resistant to Change – Hard-to-reason-about functions resist our efforts to modify them. Developers are going to be less sure about where to make changes. Bugs hide and breed in long functions.  

 

They lead to Concurrent Changes – Monster functions with many responsibilities act as a magnet to change requests. It’s their many responsibilities that make them central to an application. Several developers working in the same function can lead to tricky merge problems.

 

They are tedious to Step Through – When debugging large, convoluted functions, we’ll often need to step through the code to understand its behaviour. Much of the stepped-through code will be irrelevant to us, yet we must go through it. New developers quickly learn to use the debugger’s ‘Run to Breakpoint‘ feature. 

 

They are Hard to Unit Test – Large functions require much setting up for unit tests—if they can be unit tested at all. Due to their responsibility load, they frequently need ‘faking out’ of many dependencies. Unsurprisingly, they are usually devoid of unit tests.

 

They offer No Reuse – A 500-line method will not be highly cohesive. It will have multiple different responsibilities cobbled together. Code fragments we would like to reuse elsewhere are mixed in with other code. It might be not easy to extract it—the code is immovable.

 

It’s no surprise that metrics on function size are a prime indicator of code health. :-)

Hopefully, I have made a convincing case for shorter functions. 

Imagine how quickly our codebase would improve if we broke down our longest functions into smaller ones. 

 

So, how long should a function be? 

I’ll share my view on the ideal function length next time. 

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply