Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Sometimes (rarely), it seems that creating a function that takes a decent amount of parameters is the best route. However, when I do, I feel like I'm often choosing the ordering of the parameters at random. I usually go by "order of importance", with the most important parameter first.

Is there a better way to do this? Is there a "best practice" way of ordering parameters that enhances clarity?

share|improve this question
4  
Named parameters make this less than an issue. Python takes it to the extreme, look into it. A good example is in C# - the many ways to call MessageBox.Show. Look into that as well. –  Job Aug 16 '11 at 1:54
5  
In Haskell, the possible usefulness of partial function application usually suggest a natural argument ordering. –  tdammers Aug 16 '11 at 6:00
    
What would you consider a decent amount of parameters? –  Chris Aug 17 '11 at 2:01
    
I was thinking > 2. Though I guess ordering applies to 2 parameters all the same. –  Casey Patton Aug 17 '11 at 2:13
    
in loosely typed languages like JS you should use an options object for all fine details. –  zzzzBov Aug 19 '11 at 3:23

12 Answers 12

up vote 38 down vote accepted

In general: use it.

Write a test for your function, a real world test.
Something you would actually like to do with that function.

And see in what order you did put those down.

Unless you already have (or know of) some functions that do something similar.
In that case: conform to what they do already, at least for the first arguments.

e.g. Do they all take a document/object/file-pointer/series-of-values/coordinates as the first argument(s)? For god's sake conform to those arguments.

Avoid confusing your coworkers and your future self.

share|improve this answer
19  
+1 for "Avoid confusing ... your future self." –  Slomojo Aug 16 '11 at 3:03
5  
"Avoid confusing ... your future self" sounds like a good philosophy in general. –  Jeanne Pindar Aug 16 '11 at 3:45

I've never seen a documented "best practice" regarding this particular topic, but my personal standard is to list them either in the order in which they will appear in the method they're being used for or if the method is more of a pass-through to a data layer I will list them in the order they would appear in the db schema or data layer methods.

Also, when there are multiple overloads of a method, I notice that the typical manner is to list them starting with parameters that are common to all (or most) of the methods with each different method being appended to the end for each method overload like:

void func1(string param) { }
void func2(string param, int param2) { }
void func3(string param, string param3) { }
void func3(string param, int param2, string param3) { }
share|improve this answer

I try to put the IN parameters first, OUT parameters second. There are also some natural ordering, e.g. createPoint(double x, double y) is strongly preferrable to createPoint(double y, double x).

share|improve this answer
4  
Sometimes the opposite is better, e.g., when there's always just one OUT argument and a variable number of in arguments, like in addAllTo(target, something1, something2). –  maaartinus Aug 16 '11 at 4:02

I often follow the C/C++ convention of placing the const parameters first (that is, the parameters you pass in by value), and then those that you pass in by reference. This may not necessarily be the correct method of calling functions but, if you are interested in how each compiler handles parameters, have a look at the following links for the rules governing and/or the order that parameters are pushed onto the stack.

http://msdn.microsoft.com/en-us/library/zthk2dkh%28v=vs.80%29.aspx

http://en.wikipedia.org/wiki/Calling_convention

share|improve this answer
    
Another link that you may be interest in is msdn.microsoft.com/en-us/library/984x0h58%28v=vs.71%29.aspx For recursive functions, have a look at the following link. publications.gbdirect.co.uk/c_book/chapter4/… Not that I forgot but, being a new user I am unable to post a comment that has more than two links....how frustrating! –  Bill Aug 16 '11 at 2:14

I usually go with these rules, though not always with the same precedence. I guess it's an automatic thought-process now, and I don't over-think it, except for public API design.

Selection Funnel

  1. Semantics
  2. Importance / Relevance
  3. Frequency of Use
  4. I/O Concerns

1. Semantics First

Especially in OOP, pick parameters based on their semantical significance for the action or message. The signature of a well-named method with a well-named parameter should:

  • feel natural to call,
  • be self-descriptive in terms of intent and behavior.

(For these reasons, sometimes using custom types or aliases instead of primitives might increase the expressiveness of your signature.)

2. Then Importance

The most "significant" parameter comes first (or next...)

3. Then Frequency

The frequency matters as well, especially in a language where you don't have named parameters but can have default values on positional parameters. That implies that the order of the parameters doesn't vary, and that obviously you cannot set the N + 1 parameters if you want to force the default value of the Nth parameter (except if your language has a concept of a place-holder parameter).

The good news for you is that usually, frequency relates to importance, so that goes hand in hand with the previous point. And then it's probably up to you to craft your API for it to have the appropriate semantics.

4. Let's Not Forget I/O

if your method/function takes some input and produces an output, and the latter is not to be "returned" (via a return statement) or "thrown" (using an exception system), then you're left with the option to pass values back to the caller using your other parameters (or the input parameter). That relates to semantics, and in most cases it will make sense to have the first parameters define the output, and the last parameters receive the output.

Additionally, an other approach to have less parameters and maximise semantics would be to use a functional approach, or to define a Builder pattern, so you can clearly stack up your inputs, define your outputs, and retrieve them when need be.

(Notice I don't mention global variables, because why would you use one, right?)


Some Things to consider

  • Usability

    Most of the above will show naturally if you follow ZJR's advice: Use It!

  • Consider Refactoring

    If you worry about parameter ordering, maybe this worry finds its root in the above and in the fact that your API is badly designed. If you have too many parameters, something can most probably be componentized/modularized and refactored.

  • Consider Performance

    Keep in mind that some languages' implementations will incur very important impacts on your runtime memory management when using parameters. Hence the reason why many languages' style-books recommend to keep the parameter list simple and short. At 4 parameters max, for instance. I leave it as an exercise for you to figure out why.

  • Bevan's answer and mention of Clean Code's recommendations are definitely relevant as well!

share|improve this answer

I usually just go with the "what looks less cyprtic" parameter ordering. The fewer times that I need to go to the method/function definition the better. And it's nice to have named parameters that are descriptive as to what they are used for, that way when the little tooltip pops up (VS) then it makes it even easier.

If you have lines and lines of parameters you may want to consider a different design. Step back and see how you can break that up into more functions/methods. Just an idea, but when I have a dozen parameters in my function it's almost always not a parameter issue, but a design issue.

share|improve this answer
2  
"cyprtic": a great way to make the point. –  Bevan Aug 16 '11 at 3:40
1  
You've never had a typo before, @Bevan? –  user29981 Aug 16 '11 at 4:06
    
I have typos all the time - writing cyprtic was so good I thought it was on purpose. Please do change it back, it helps to make your point, even if it was an accident. –  Bevan Aug 16 '11 at 4:14
    
@Bevan, haha okay I see what you're saying. Good point! Its changed back =) –  user29981 Aug 16 '11 at 10:38

Order: input(s), output(s), optional parameters.

share|improve this answer

I'd respectfully submit that worrying about parameter ordering is worrying about the wrong thing.

In Uncle Bob's book "Clean Code" he advocates, persuasively, that methods should never have more than two arguments - and most should have only one, if any. When this is the case, ordering is either obvious or unimportant.

However imperfectly, I'm trying to follow Uncle Bob's advice - and it's improving my code.

In the rare cases where a method seems to require more information, introducing a parameter object is a good idea. Usually, I find this is the first step towards discovery of a new concept (object) that's key to my algorithm.

share|improve this answer
    
I definitely agree with you! My first statement was aimed to get at the point that this isn't a typical thing for me, haha. But in the case that I find I really do need to pass some parameters and it's not worth it to refactor the whole program, I wonder about ordering. –  Casey Patton Aug 16 '11 at 4:06
2  
cough PHP cough. I'm sorry - you were saying something about not worrying about the order of parameters? –  Craige Aug 16 '11 at 15:26
    
Won't you then just have a constructor for your parameter object that takes just as many arguments? –  detly Mar 9 '12 at 2:02
    
No - because the parameter object can be "built up" over several statements in a way that's more readable. –  Bevan Mar 9 '12 at 3:17
    
@Bevan: this is highly debatable. Building up objects this way means they can't be immutable anymore; keeping your objects immutable whenever possible however is another great way of increasing maintainability. –  tdammers Mar 9 '12 at 16:49

Oftentimes a complex object as a parameter is better -- a poor man's version of named parameters that works on most platforms. And opens the door to parameters with behavior to boot.

For an example of most things you shouldn't do you might want to try reading PHP's standard library documentation.

share|improve this answer

I usually order them with required first, than by some combined measure of importancy and frequency of use according to a "feeling" (can be seen as ORDER BY required DESC, SOME_MAGIC_FEELING(importancy,frequency)) and not according to any specific practice.

However, as others have noted, I think the underlying problem that makes this an issue is using too many parameters (IMHO, anything >3 is too many) and that's the real problem that you should be addressing. There's an interesting post about that at rebecca murphey's blog.

I think that when you only have 1-3 arguments, the correct ordering is quite obvious and you just "feel" what's right.

share|improve this answer

Similar to @Wyatt Barnetts' answer, anything more than a few parameters or very explicit parameters for the method, I'd recommend passing an object instead. This is typically easier to update/maintain, clearer to read, and removes the necessity for worrying about ordering. Also, too many parameters for a method is a code smell and there are common refactoring patterns you can follow to help correct it.

Explicit example:

public int add(int left, int right)
{
  return left + right;
}

Since this is a pretty clearly defined example and addition is commutative (order doesn't matter) then just go with it.

However, if you add something more complex:

public SomeComplexReturnValue Calculate(int i, float f, string s, object o)
{
  // do work here
}

Would become:

public class SomeComplexInputForCalculation
{
  public int i; 
  public float f;
  public string s; 
  public object o;
}

public SomeComplexReturnValue Calculate(SomeComplexInputForCalculation input)
{
  // do work here
}

Hope this helps...

share|improve this answer

Order it in whatever way you think currying will most likely benefit from. For example, function parameters first.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.