Blog of Rob Galanakis (@robgalanakis)

Optional parameters can be harmful

I’ve come around on optional parameters after being an opponent of adding them to .NET.  They can be very helpful, clean up the code by not needing overloads, and inform the caller what the defaults are.  They are an integral part of python and why it is easy to use.  This is great.

Except when you abuse them.
And you may be abusing them without knowing it.

Parameters should only be optional if a valid default value can be determined by looking only at the contents of the method.

What do I mean?  Well, if your default value is ‘None’, and you call another module to create the actual default value, this is not good practice.  It negatively impacts two important software metrics: it increases coupling by adding a dependency on your module, and it increases cyclomatic complexity by creating an ‘if’ statement.

It is better, in these cases, to just force the user to pass in a valid value.  If you’re jumping through hoops to determine a default value, odds are it is too specific and also breaks the reusability and dependability of the method.  The caller has a higher chance of already having a dependency to what you would be depending on for your default value (any chance is higher than the 0% chance your method has of needing it).  To demonstrate:

def exportFile(filename, branch=None, depotRoot=None):
    if branch is None:
        branch = os.environ['EXPORT_BRANCH']
    if depotRoot is None:
        depotRoot = someScmModule.singleton.depotRoot
    ...

This code is not unusual but it is really difficult to understand and maintain.  The default values determined for branch and depotRoot are entirely outside the logic and goal of the method.

Don’t do stuff like this and you (and especially others!) will have a much easier time maintaining and supporting code.

Leave a Reply