in reply to Re^2: How should named paramater keys be named?
in thread How should named paramater keys be named?
However, if it is an interface exposed to the public where you are not certain of the ordering, then named parameters may be in order.
You really think that remembering the ordering of parameters is harder than remembering the names, spelling, casing, presence or absence of leading hyphens etc?
Do you you use (or just know of) a non-constructor api that you feel really benefits from the use of named parameters?
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^4: How should named paramater keys be named?
by Corion (Patriarch) on Jul 02, 2011 at 07:53 UTC | |
The LWP::UserAgent/WWW::Mechanize API (and especially the WWW::Mechanize::Firefox API) has lots (and lots) of optional parameters, which are mostly filled in as defaults from the object when left out or left alone. The first such example in WWW::Mechanize::Firefox is
... where you specify the callbacks by name instead of by position, as usually, you want only to set one or two callbacks. The same counts for the ->get() method:
Here, the options can specify a target filename where to store the response, whether to bypass the cache etc.. All of these parameters are fairly orthogonal and it wouldn't make much sense to have them positional in my opinion. Two APIs that constantly trip me up is the DateTime API and the Imager::Color API. The DateTime API wants me to always specify named parameters when I'm calling any function even though the method only allows one parameter and makes sense for only one parameter. The Imager::Color API raises no warning for:
... but creates no sensible object either. It wants
| [reply] [d/l] [select] |
by BrowserUk (Patriarch) on Jul 02, 2011 at 08:55 UTC | |
where you specify the callbacks by name instead of by position, as usually, you want only to set one or two callbacks. Optional arguments are the exception that proves the rule. (IMO :) The DateTime API wants me to always specify named parameters when I'm calling any function even though the method only allows one parameter and makes sense for only one parameter. And that demonstrates the problem with guidelines. There will always be those who apply them religiously without thinking. Cargo-culting of the very worst kind. Another that bugs me is q(). The Imager::Color API raises no warning for: ... but creates no sensible object either. I liked the SmallTalk approach to the problem where the names of arguments to methods are effectively a part of the method identifier. Eg.
The best bit about this is that the parameter names are checked at compile time. Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [d/l] [select] |
by tonyc (Hermit) on Jul 13, 2011 at 07:48 UTC | |
That behaviour of Imager::Color would be a bug, given the documentation. But I can't reproduce it:
| [reply] [d/l] |
by Corion (Patriarch) on Jul 13, 2011 at 07:52 UTC | |
Maybe the problem was in my subsequent use of the colour - I have to look at the code at home to see what really triggered the behaviour in the program. Looking at the code in Imager::Color, I don't see any reason why it shouldn't behave as the documentation says. | [reply] |
|
Re^4: How should named paramater keys be named?
by DeadPoet (Scribe) on Jul 02, 2011 at 22:15 UTC | |
Once again it depends on the complexity of the parameters that are being supplied. One, two, three parameters exposed to the public maybe not an issue, and agreeably named parameters probably not needed. However, if the interface in to the whatever you are calling requires a more complicated set up, then I would say that named parameters are in order. Now with that said, when using named parameters they better be consistent throughout the entire program. Moreover, I would go so far as to say they should also be lower case and clearly documented. Personally I see named parameters having value, but the value is only obtained where exposed to the public. Code that is on the back end that users cannot call directly why would they be needed--you already have established programmatic control over the parameters. Yes, I use named parameters outside of a constructor -- my previous restrictions still apply ( internal NO, user called YES ). An example would be when I want to enable a local debug. Keep in mind that the routine already has other values being passed.
Now, I did not run check the code above, and it is ONLY an example of what can be done. Also, I do not expect everyone to agree with the code. So, not only does this allow a user to call the function, method, subroutine, etc... but it provides simple named parameters by which it can be called. More importantly, it allows the end user to call it without having to care about the order and if the parameter is not specified then it is defaulted. I understand that one cannot always default to a meaningful value, but this is just an example. As far as my style goes, I do not like the leading hyphen, nor do I like the mixed case, such as the DBI Connect implements. But that is just my style. Honestly, I prefer the shorter single case format. Finally, named parameters have their place and can provide value. The trick is to balance how and when they are used. Is there a cost? Yes. Can they provide a more robust public interface? Yes. Can they be overused? You better believe it. | [reply] [d/l] |
by BrowserUk (Patriarch) on Jul 03, 2011 at 11:58 UTC | |
The problem with your arguments is that they are based upon emotion rather than logic. Your preferences rather than clear reasoning. There *is* utility in using named parameters for sub/methods that (usefully) take large numbers of optional parameters. And that mostly means constructors. There are examples of non-constructor functions/methods that could have many optional parameters--fetching a url (get) is one such with all the possibilities of headers, agent ids, cookies, redirects, time-outs et al. But even then there are good ways and bad ways of defining the API. Most of the options used by get() for any given application are unlikely to change for every fetch. So, whilst the run-time of a fetch is likely to always be dominated by the IO, it simply doesn't make sense to re-parse and re-validate those options for every individual fetch, so using the options to construct a user agent, and then have the $ua->get( $url ) as a simple method of the user agent is just good design. Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [d/l] [select] |
by DeadPoet (Scribe) on Jul 03, 2011 at 14:45 UTC | |
I hear your arguments, and did state that this is just an example of what can be done. I also do not think I have ignored your argument of parameter checking, as I stated early on that there is no excuse for not checking parameters and return codes. I also stated that not always can a value be defaulted--this example just provided a way of showing setting a default value. Poorly chosen or not, this is a simple example to illustrate. I always enjoy conversing with you on matters, as I enjoy the different point of view. But let us remember, Examine what is being said, not who is saying.... This was just a quick example, and all I have said is that named parameters can have value. If it is your stance that they can have no value, then I respectfully disagree. There is a product called PowerKeeper that implements a programmatic interface much as you have described-- foo( opt1, opt2, opt3, optn ). Let's just look at the AddSystem API for a moment:
There are 47 options, and none named. Moreover, all parameters are position dependent. So by your logic, it is easier to remember that the 'CheckFl' belongs in field 26? I think this is the spirit of the PBP when it comes to when to use named parameters. To exclude possibility is to limit oneself, to blindly accept is to subjugate ones mind, to explore is to learn. --Poet | [reply] [d/l] |
by BrowserUk (Patriarch) on Jul 04, 2011 at 01:11 UTC | |