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.

A long time ago I programmed a lot in ADA, and it was normal to name arguments when invoking a function - SomeObject.DoSomething(SomeParameterName => someValue);

Now that C# supports named arguments, I'm thinking about reverting to this habit in situations where it might not be obvious what an argument means.

You might argue that it should always be obvious what an argument means, but if you have a boolean argument, and callers are passing in "true" or "false" then qualifying the value with the name makes the call site more readable.

contentFetcher.DownloadNote(note, manual : true);

I guess I could create Enums instead of using true or false (Manual, Automatic in this case).

What do you think about occasionally using named arguments to make code easier to read?

share|improve this question
    
Parameter comment on top of methods also helps. –  Amir Rezaei Feb 28 '11 at 12:16
1  
@amir-rezaei: Parameter comments on top of methods only help if you can trust the comments. Unless you have good developers and good code review processes, I wouldn't trust the comments. –  btilly Feb 28 '11 at 18:44
    
As a one-time Ada user myself, I'm for occasional use as you describe. That's how I remember them being used in Ada, BTW - I wouldn't call it "abnormal", but the word "normal" seems to imply most calls would specify parameter names, which isn't how I remember things. Of course conventions vary, but unnecessary clutter is a bad convention in any language IMO. –  Steve314 Feb 28 '11 at 21:16
    
I agree re your use in Ada - it wasn't something we did all the time, but where it helped. –  Damian Feb 28 '11 at 23:55
add comment

5 Answers

I agree that adding the parameter name makes it more readable. However, most of the books I've read seem to consider boolean switches to be a bad practice. I sometimes do this:

public Content DownloadNote(Note note)
{
    return downloadNote(note, manual: false);
}

public Content DownloadNoteManually(Note note)
{
    return downloadNote(note, manual: true);
}

That does give you more flexibility when implementing your API. It also allows you to control the case where you have multiple boolean switches, but not all of them can be active at the same time.

share|improve this answer
2  
If you have x choices, will you make 2^x frontends? –  apoorv020 Feb 28 '11 at 14:34
    
@apoorv020 - if I had enough parameters to a method call that 2^x became significant, I'd make a new class to hold the parameter values, and just pass one parameter. –  Scott Whitlock Feb 28 '11 at 18:25
    
@scott-whitlock: Option 1 - create an object, set x properties, call a method once with your object. Option 2 - call a method with x named parameters. Which is better depends on your language. In a dynamically typed language, option 1 requires significantly more boiler-plate with no gain, and so is worse. In a statically typed language you still add the boilerplate, but tests for incorrectly named keys get to be done at compile time rather than run time. Therefore option 1 is better in C#, but option 2 is a clear win in Python. –  btilly Feb 28 '11 at 18:40
    
@btilly - as Ian pointed out, Clean Code clearly tells you not to have functions with more than 2 or 3 parameters. To be fair, it was dealing with Java, which is statically typed. The OP is also asking about C#, which is statically typed. I would still prefer to use function overloads and/or different precisely named function names than a long list of parameters. –  Scott Whitlock Feb 28 '11 at 20:06
    
@scott-whitlock: Do we actually disagree? We agree on what is best in C#. We both know what Clean Code says. My point was that it is important to understand why it is good, so that you know when the advice does or does not fit a different environment. –  btilly Feb 28 '11 at 22:48
add comment

I think this is issue of making bad code more readable, rather than “best practice”.

Having a method (or contractor) that takes 20 parameters is a “bad smell” and is likely to be due to a problem in your design. However if I am forced to work on code when methods take a lot of parameters, then named parameter make the code less hard to understand.

When methods only have 1 or 2 parameters and it is clear from the method name what the parameter are, then named parameter add nothing. This is the ideal case to be in.

If all the code you work on is written as par the “clean code” book, then you will have very little use for named parameters, however we live in the real world.

share|improve this answer
    
A function with two parameters can be confusing, if both parameters are the same type and with no clue to which is which. Of course you can name the function in a way that provides that clue, but you're really just doing what the parameter names do anyway - except that you make it compulsory to include that verbosity even when the context (e.g. the expressions that supply the parameters) make it obvious which parameter is which. –  Steve314 Feb 28 '11 at 21:19
add comment

I think this is more useful in non-OO languages, where you may have one function that has to do something in several slightly different ways, and the way it determines what to do is based on parameter values. In the OOP world, we would just overload the function, but when that's not possible then you wind up passing a bunch of flags (or a bunch of values, and whether or not they're passed is the flag).

I think it's more readable, to an extent; but as others have mentioned, having many parameters is a code smell, so I don't see a whole lot of use for this in an object-oriented language like C#.

share|improve this answer
add comment

This was suggested in the development of C++, and Stroustrup discusses it in his "Design and Evolution of C++", pages 153 and following. The proposal was well-formed, and drew on prior experience with Ada. It wasn't adopted.

The biggest reason was that nobody wanted to encourage functions with large numbers of parameters. Each additional feature in a language costs something, and there was no desire to add a feature to make it easier to write bad programs.

It also raised questions of what the canonical parameter names were, particularly in the usual header and code file convention. Some organizations had longer and more descriptive parameter names in the .h file, and shorter and easier to type names in the .cpp file (substitute file suffixes as desired). Requiring that these be the same would be an additional cost on compilation, and getting names mixed up between source files could cause subtle bugs.

It can also be handled by using objects rather than function calls. Instead of a GetWindow call with a dozen parameters, create a Window class with a dozen private variables, and add setters as necessary. By chaining the setters, it's possible to write something like my_window.SetColor(green).SetBorder(true).SetBorderSize(3);. It's also possible to have different functions with different defaults that call the function that actually does the work.

If you're just worried about the documentation effect of contentFetcher.DownloadNote(note, manual : true);, you can always write something like contentFetcher.DownloadNote(note, /* manual */ true);, so it's not even very helpful in documentation.

share|improve this answer
    
Funnily enough when I moved from Ada to C, I started using the convention you describe - code reviewers hated it though. Agree re not using it for large numbers of parameters. –  Damian Feb 28 '11 at 22:38
add comment

I'm a big believer in named parameters in situations where the types and semantics are not clear from the name of the method. My experience is that few folks read the documentation.

That being said, named parameters should not be an alternative to making sensible argument lists, using helper objects (to "tie" together semantically related arguments), and using enumerations where relevant.

share|improve this answer
add comment

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.