Art of Coding: Too Many Arguments!
You ever encounter a function call (in any language) that took six or more arguments? Or, worse, used "Variable Arguments" like **kwargs, and all that grossness? Did it make you feel dirty?
It should. You should feel dirty when you write dirty code.
If you don't feel dirty that does not mean you're lazy, it just may mean your college professor didn't teach you the proper ways of developing software. Your teacher was lazy. It happens (a lot). Or, maybe you were. It's time to get better.
How Many Is Too Many?
def myFunction(parmA, parmB, parmC, parmD, parmE=None):
In "the old days" we were told once you have more than 3 or 4 parameters, it's time to consider a data structure. This was traditionally done for optimization and conserving the call stack, memory and all those "old timey words".
However, this art seems to have gotten lost somewhere along the line, engineers took the fast and sloppy route of variable arguments, or just large strings of arguments. Variable arguments are argued to be more "extensible" and flexible... all probably true, but at what cost? Just because you can do a thing does not mean you should do a thing.
func2(paramA, paramB, **kwargs):
... code goes here ...
func1(pA, pB, pC, **kwargs):
func2(pA, pC, **kwargs)
The above code is entirely "legal" in Python, but that doesn't make it good style. Let's quickly identify the issues:
There are exceptions to this rule, the traditional C-style printf is a great example, it was designed with the intention of allowing a developer to pass a format string and a list of format operations; it was a creative way to solve a complicated problem. However, being creative doesn't always work. Sometimes being simple leads you down the path to salvation.
As a solid rule, if you plan to have more than 3 parameters, plan differently.
Take The Time To Do It Right
When you start down the path to the 4th parameter you must ask yourself "is this truly it? Will there ever be a need to expand more?" If the answer is "uncertain" then it's time to change the game plan, or at least write a comment in your function that reads something like "if we need more parameters, refactor" to remind yourself.
Recommended by LinkedIn
Doing things right is hard and slow. It requires more thinking. It means you may need to break out an additional 10 minutes or more to do it right... adding "just one more parameter" takes milliseconds. However, the value in doing things right adds up over time.
Readability, Documentation, and Respect
I always assume I will eventually hand the code off to someone else to maintain. This may be as I move on to a new company, a new team, or if I'm hit by a bus. Readable code serves multiple purposes:
If you always believe that you will someday hand over your code to another individual, you will begin to code with that in mind everyday. It may be in a few additional code comments for the reader (or code reviewer), it may be a nice clean code style that they can scan fast, or it could allow others to assist you in writing documentation on your project someday in the near future.
Data Structures > 4+ Parameters
If you're going to be passing a larger list of parameters to a function, create a data structure to store them all. In python, we can do this with classes such as:
@dataclass
class ParamSet
""" The param set class example for awesomeness """
paramA: str
paramB: int
paramC: str
paramD: myClass
paramE: int=0
def func1(params: ParamSet):
... code goes here ...
By breaking out all our parameters into a class (or "dataclass" decorator for simplicity) we gain all type of advantages. For instance, we now set ourselves up for some standard best practices for documentation, such as type hinting (in Python), and commenting your structure (so users know what it does). You can also set some reasonable defaults, or even comment each parameter with "why" and "what" it does. We can also write new private (or public) class methods to tweak, print, or do complicated modifications to parameters.
Yes, you'll probably gain some call stack optimization by passing one parameter vs. six or more... but in Python you often aren't concerned with that level of optimization. However, the human factor of optimization should be priority 1. Engineers will read your code faster, understand it faster, and be able to support it faster -- that is a huge optimization increase.
Bottom Line
By taking the additional time to design out a data structure to pass parameters around gives you many chances to guide your reader to the final conclusion by allowing for data type hinting, comments, as well as allowing future engineers to add new parameters to your object, instead of adding it to the end of a function that has been called 30 times and now you have to go update all the references to the function.
It's hard to stop what you're doing and refactor your code when you can just add "one more parameter". But, if you don't do it, why should the next person in the code do it? Then, four years later the new hire is saying "so...why does this thing have 9 arguments?" and the only answer is "yeah, we probably should fix that."
Don't invent TECH DEBT. Just do it right the first time.