"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


Reply via email to