Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What to do when function has too many arguments?

I develop a system in Clojure. I try to write it as functional as possible. One of things is referential transparency (for same arguments function should always return the same result).

The problem is that some functions (especially my views and partially controllers) get too many args (like 5-6 and probably more in future).

How would you solve that problem?

I see couple of possible solutions each has pros and cons.

1) create ParameterMap - put parameters to Map and validate it with schema (https://github.com/prismatic/schema) - this is preferred solution but problem with this solution is that I get runtime errors instead of compile-time errors (now application refuse to compile because of bad arity when I forgot to refactor some part of application)

2) use closures - closure can capture named variables and wait for the rest. It checks on compile time. This solution is simple but makes me to create closures just to split amount of arguments to more functions which I see like functional-way to do anemic design. This solution is similar to use of monads where nobody seems to see adding arguments in steps as something unclean which I don't understand why.

3) turn parameters to named parameters - I will still have large amount of parameters but they stop being unclear because I can see what they mean on the first sight. I used this approach in other parts of application and it works. Unfortunately this is prone to NullPointerException in runtime and doesn't check in compile time.

like image 205
Jiri Knesl Avatar asked Mar 17 '14 16:03

Jiri Knesl


People also ask

Do I have too many arguments in my if statement?

Re: Too many arguments? IF has three arguments: A test, output when true, output when false. Your 4th IF contains a test, true statement, a false statement, and a 4th argument ",IF (A2="ACT",K2&".21")". You will need to reconcile the False statement with how you wish to incorporate your final IF function.

Is it possible to have too many parameters in a function?

Many times, we tend to add too many parameters to a function. But that's not the best idea: on the contrary, when a function requires too many arguments, grouping them into coherent objects helps writing simpler code. Why? How can we do it? What are the main issues with having too many params? Have a look at the following snippet:

How to reduce the number of arguments in a function?

Another technique is the pattern mentioned earlier, the Parameter Object pattern. We can aggregate arguments that are within same context, and then create a plain object containing those arguments. In next example, I’m going to show how to use the Parameter Object to reduce arguments’ number using the sample function showed earlier:

What is the ideal argument number for a function?

Uncle Bob (Robert C. Martin), in the Clean Code book, explains that an ideal argument’s number for a function is zero (niladic function). Followed by one (monadic function) and closely by two arguments (dyadic function).


2 Answers

Well, the answer is highly dependent on your codebase but is likely a combination of all of these things.

It's not a matter of choosing one or the other, it's choosing what works best for the various specific functions. For example, you should use closures where closures make sense, named params where those make sense, and maps when those make sense.

If you've got a bunch of arguments and you're passing these common arguments around to numerous functions, it likely does make sense to use a map to contain them and make it clearer what the arguments actually are.

like image 151
Rayne Avatar answered Oct 16 '22 17:10

Rayne


An extended comment:

Paul Graham wrote the following about a DSL called Rtml (in which programs are called templates):

Rtml depended heavily on keyword parameters, which up to that time I had always considered one of the more dubious features of Common Lisp. ...

If I wanted to add another dimension to the behavior of one of the operators, I could just add a new keyword parameter, and everyone's existing templates would continue to work. A few of the Rtml operators didn't take keyword parameters, because I didn't think I'd ever need to change them, and almost every one I ended up kicking myself about later. If I could go back and start over from scratch, one of the things I'd change would be that I'd make every Rtml operator take keyword parameters.

like image 20
Thumbnail Avatar answered Oct 16 '22 18:10

Thumbnail