[Reposting this from earlier this week, since it didn't seem to make it to the news server. -dmw]
A question about the calling syntax of named parameters versus arguments supplied to a slurpy hash. If I understand A6 and A12 correctly, all Pair arguments to a function (sub, method, etc.) are scanned to see if their key is a parameter name, and if so, its value is passed as the parameter's argument. Otherwise, the Pair is bundled up into a slurpy hash if one is defined; if no slurpy hash is defined and there are still pairs in the argument list, it is a compile-time error. So far, so good. My concern is that given an argument supplied as a pair (foo => "bar"), it is not clear which type of parameter is meant to be supplied. If there is no such named parameter, we know that the argument was intended for the slurpy hash. However, what if the method designer later adds an optional parameter, often to be implemented as a named-only parameter +$foo? (Or rather as ~$foo if you agree with another post of mine ;-) Existing code providing the same parameter name as a key for the slurpy hash may now break, since the target (slurpy hash) was not clear. An example may clear up the issue. Imagine we have: sub logError($msg, *%errorInfo) { my Str $s = $msg; for %errorInfo.kv -> $k, $v { $s ~= "; $k=$v"; # append error info meta-data to error message } print "ERROR: $s.\n"; } User code is now liberally sprinkled with log statements like: 1. logError("Username not found"); 2. logError("Cannot login", module => "DB.pm", line => 68); 3. logError("Database error", module => "DB.pm", line => 263, prio => "HIGH"); Later on, the logging API is augmented to specify the logging priority directly. Since we don't want to have to modify every existing log statement, we add an optional named priority parameter, with a default: sub logError($msg, Int +$prio = 4, *%errorInfo) { my Str $s = $msg; for %errorInfo.kv -> $k, $v { $s ~= "; $k=$v"; # append error info meta-data to error message } # translate numeric priority level [1-7] to # a String description like "ERROR", "ALERT", etc. my Str $prio_desc = getPrioDescription($prio); print "$prio_desc: $s.\n"; } Most of the existing calls will work fine. But what about calls like #3 above: logError("Database error", module => "DB.pm", line => 263, prio => "HIGH"); After the New And Improved logError() routine is rolled out, it seems to me that this log statement should generate a compile-time error, since the named Int parameter "prio" is given a non-integer argument "HIGH". At best, this should be a run-time error. Either way, this confusion undermines a key Perl strength: ability of the user to upgrade code (without breaking it). I have thought a bit about possible fixes, and while there are many possible, I think the best approach would be to separate the related but distinct concepts of supplying an argument to a named parameter from the general Perl 6 notion of a Pair. Reusing the Pair creation operator '=>' for named parameter binding is a nice use of orthogonality, but perhaps reminiscent of the too-orthogonal object-oriented notation in Perl 5 (as Larry nicely laid out in A6). What we really mean by logError($err_msg, prio => 3); is: "bind the argument $err_msg to the first positional parameter in logError(), and bind the value 3 to the parameter named "prio". Yes, the parameter name and argument value form a pair of entities, but that is not their essential characteristic. To distinguish these two cases, what if we used the := binding operator to bind an argument to a named parameter: logError($err_msg, prio := 3); AFAICT, the ":=" operator would currently be illegal in this context. This opens it up to this new, but highly-related, meaning. It also means that a caller can supply any number of Pair arguments, and they must map either to positional Pair parameters, or to the slurpy hash. Otherwise, it is a compile-time error. And future compatibility is ensured, since only arguments passed via ':=' will get mapped to named arguments, and only arguments that look like "foo => $bar" can get mapped to explicit Pair parameters or implicitly to a hash. If for some reason ':=' cannot work here, how about it's compile-time brother '::='? (Yes, we try to comply with Larry's First Law of Language Design: Everyone wants the colon ;-) If neither one of these operators can be used syntactically, I'd still suggest a distinct syntax for supplying these two distinct types of parameters. BTW, I understand that a slurpy hash is used in object construction via bless and friends, but what is its usefulness in the rest of the world? Whereas slurpy array [EMAIL PROTECTED] is meant to accept an arbitrary amount of anonymous "factory-supplied" data, is *%hash just a sop for anonymous meta-data? Shouldn't meta-data be explicitly declared in the signature so that the meaning of each parameter is understood? If not, we have ontological overload (i.e., I have received lots of meta-data about this method call in my method body, but I don't really know what most of it means or can be used for). I can see how this might be needed in generic object construction code, but if there's not much use for it in general user-level code, perhaps the slurpy hash is a feature in search of a purpose. It should certainly be allowed, but not without more explicit and verbose syntax, given the low Huffman need. Unless of course I am totally off here. Feel free to let me know where I may have gone wrong. I'm sure that someone will if I have ;-) -Dov Wasserman [EMAIL PROTECTED]