"Aldo Calpini" <[EMAIL PROTECTED] <mailto:[EMAIL PROTECTED]>> wrote in message <news:[EMAIL PROTECTED]>... > > if you decide to reimplement logError to be just: > sub logError { # implicit ([EMAIL PROTECTED]) > # ... > } > using a Pair, you still have someting (a Pair object) that you can > inspect, and eventually decide wether to treat as a named argument or > not. but when you use "prio := 3", what do the subroutine get? only "3" > in that position? or a Pair anyway? or it doesn't get the 3 at all?
This cuts to the heart of the meaning of named parameters vs. positionals. IMO, if you specify a parameter by name as part of a function invocation ["function" here meaning any type of sub, method, multi, etc.], the "method dispatch" must resolve only to functions with that parameter name declared in their signature. In the example you give, invoking logError() with any number of positional parameters would resolve to the subroutine defined above. But calling "logError(prio := 3)" should be a compile-time error, unless another logError function was defined with a parameter named "prio", whether named-only or positional (since positionals can always be referred to by name). When a caller passes a parameter by name to a function, that gives the compiler more information about which function is intended. I would say it is (or should be) similar to how Java resolves method calls: the declared types of the arguments determine at compile-time which method signature is meant. All other overloaded variants are ignored. Then at run-time, the most specific overridden method definition with that signature is invoked. The Perl 6 equivalent for named parameters would be: determine at compile-time the set of all matching functions of the invoked name declaring all the parameters named in the invocation. If there are none, you get a compile-time error like: "Could not find any function named 'logError' with a parameter named 'prio'." If there is more than one candidate (based on issues like optional parameters and argument types), the "best" one is chosen at run-time according to the principles in A12. Of course, there are other considerations for dispatch; I'm just referring to how parameter names should work. Whether you can overload based on nothing more than parameter names remains an open issue. I'd guess it's like return type, where Larry is leaning towards allowing override between otherwise-equal definitions. The drawback to this approach that I can see is that all parameter names are now part of the function's public API. This does run contrary to the C-derived languages, but I'm not sure how bad that really is. On one hand it does break encapsulation, but on the other, it does make clear the intended meaning of each parameter. So maybe instead of breaking the function's encapsulation, we can think of it as simply pushing up the parameter names from private scope into the public scope where they really belong. Of course, let's not loose sight of the big picture: most functions will likely not declare named-only parameters. And conversely, the user is always welcome to pass any or all positional parameters by name as they wish. However, if the function designer wishes to require that a given parameter be named, then the language should ensure that a caller meant to pass in an argument to that parameter, and not any other similar data. Function designers are always able to get the flexibility you describe above by declaring a more forgiving signature, or none at all. You can have it either way you like, just not both ways at once. TMTOWTDI, just not at the same time! BTW, please excuse my verbose responses. Now that I've started a new job, I'll be sure to be briefer in the future ;-) Regards, -Dov