Clean Code: 8 Tips to Write Clean Functions 🔥
Learn about eight practical tips on writing clean functions. (5 min)
Clean Code is code that is easy to read, maintain, test, and understand.
Clean Functions are the foundation of Clean Code.
Master clean functions and you’ll naturally write better software.
In today’s article, I’ll share 8 practical tips for writing clean functions that I follow daily in my projects and work.
Let’s dive in!
Cut Code Review Time & Bugs in Half - Sponsor
CodeRabbit is your AI-powered code review co-pilot.
It provides instant, contextual feedback on every PR, along with one-click fix suggestions. It has reviewed over 10 million PRs and is used in 1 million repositories.
Besides, it’s free to use for open-source repos; 70K+ open-source projects already use it.
CodeRabbit lets you instantly spot:
Logic & syntax bugs
Security issues (XSS, SQL injection, CSRF)
Concurrency problems (deadlocks, race conditions)
Code smells & readability concerns
Best practice violations (SOLID, DRY, KISS)
Weak test coverage & performance bottlenecks
Write clean, secure, and performant code with CodeRabbit.
#1: Keep Your Functions Small And Focused
Functions that do multiple things are hard to follow, understand, test, debug, and even reuse.
When something breaks, it’s very hard to pinpoint the exact part that failed.
When requirements change, and they do change regularly, you risk breaking the whole function and unrelated functionality.
In the Clean Code book, Uncle Bob says:
The first rule of functions is that they should be small.
The second rule of functions is that they should be smaller than that.
So each function should have one clear responsibility.
Sometimes a function might be just 5 lines of code, while other times it might be 50 lines of code to fulfill a single responsibility.
If you can describe what your function does with “and”, it probably does too much.
There’s no universal rule to draw the line.
Trust your experience and your judgment based on the context you have.
Be pragmatic. Don’t be dogmatic.
#2: Name Functions to Reveal Intent
Function names like process() or handle() force readers to examine the implementation to understand what the function does.
This slows down code reading and increases the cognitive load.
Function names should clearly state what they do with action verbs.
A good function name should answer:
“What action does this perform?” and “What does it return?”
You can also follow these tips:
Use terms and language based on the specific domain, so your functions are more tailored to the business context.
Follow the already established naming conventions.
Use verbs and verb phrases for actions (calculate, validate, send).
Use question words for boolean functions (is, has, can).
Be consistent with the naming, so you don’t use two words for the same thing.
#3: Return Early to Avoid Nesting
Deeply nested functions create a “pyramid of doom”, which is hard to follow, debug, and understand.
Your brain has to track multiple logical branches simultaneously.
The main business logic gets “hidden”, making it hard to find.
To fix this, you can use the early return principle.
You can handle edge cases and invalid inputs using guard clauses.
This removes the many levels of branches, keeping the “happy path” obvious, clear, and easy to follow.
#4: Limit Function Parameters
Functions with many parameters are a cognitive load.
You can’t remember parameter order, and it’s easy to pass the wrong values.
To improve this, group related parameters into objects.
This reduces cognitive load and makes parameter order irrelevant.
#5: Write Pure Functions When Possible
Functions with side effects are unpredictable.
They might work differently based on a global state, making them hard to test and debug.
You can’t reason about them in isolation.
They also cause mysterious bugs in unrelated parts of the system.
To mitigate this problem, strive to write functions that depend only on their inputs and produce no side effects.
Pure functions are predictable, testable, and can be safely called from anywhere.
And we can also run them in parallel.
#6: Avoid Boolean Parameters
Boolean parameters make function calls unclear and hard to extend.
When you see processOrder(order, true), you can’t tell what true means without checking the function definition.
Boolean flags also often indicate that a function is doing two different things.
A better approach is to use objects, enums, or separate functions instead of single boolean flags.
This makes your code self-documenting and easier to extend.
#7: Return Results, Not Exceptions
Using exceptions for expected failures makes error handling invisible and easy to forget.
Callers don’t know what can go wrong just by looking at the function signature.
This leads to unhandled edge cases and application crashes.
To fix this, apply the Result Pattern and make errors part of your return type.
This forces callers to handle error cases and makes your function’s behaviour predictable and explicit.
A good rule of thumb is:
Use Result Pattern for expected errors to make them explicit.
Use Exceptions for unexpected errors and exceptional situations.
#8: Replace Magic Numbers and Strings
A common code smell is the use of magic numbers and strings.
These hardcoded values create a maintenance nightmare.
When business requirements and rules change, it’s very hard to find every occurrence of these numbers or strings.
Another big problem with these magic numbers and strings is the lack of meaning.
To fix this problem, extract the numbers into constants and the strings into enums.
📌 TL;DR
That’s all for today, 8 tips to write clean functions:
Hope this was helpful.
See you next week!
Today’s action step: Take a look at your project and see if you’re making some of the mistakes I highlighted here. Try to fix them using the clean code tips I shared with you.
👋 Let’s connect
You can find me on LinkedIn, Twitter(X), Bluesky, or Threads.
I share daily practical tips to level up your skills and become a better engineer.
Thank you for being a great supporter, reader, and for your help in growing to 27.4K+ subscribers this week 🙏
Love it! I wish you were on my team.
I would add that comments are a code smell, and you can easily work the comment into a well named function, class, or variable.