On Fri, Feb 18, 2005 at 04:25:49PM +0800, Autrijus Tang wrote: : After getting Life and Mandel to run on Pugs yesterday (see : http://svn.perl.org/perl6/pugs/trunk/examples/ ), today I've : made this version of Quicksort to run: : : use v6; : : multi sub quicksort ( ) { () } : : multi sub quicksort ( *$x, [EMAIL PROTECTED] ) { : my @pre = @xs.grep{ $_ < $x }; : my @post = @xs.grep{ $_ >= $x };
Just as a BTW, that syntax is illegal currently, since those curlies would be interpreted as hash subscripts. Method syntax requires parens if there are any (non-adverbial) arguments. So you either need parens for the argument: my @pre = @xs.grep({ $_ < $x }); my @post = @xs.grep({ $_ >= $x }); or pass an adverbial block: my @pre = @xs.grep:{ $_ < $x }; my @post = @xs.grep:{ $_ >= $x }; : (@pre.quicksort, $x, @post.quicksort); : } : : (1, 5, 2, 4, 3).quicksort.say; : : Note the use of @xs.grep{} above. Pugs currently has two multisub : named "grep": : : * List as invocant, takes a Code arg : * Takes two args: Code and List : : It sort of makes sense to me. Please correct me if it's wrong. :) As long as the first is always called as single dispatch, and the second as multiple dispatch, there should be no confusion. : But anyway. The real problem is the multisub dispatcher initially : complained about the () signature, saying that it is "non-slurpy" : and may not take a list, even though the list eventually flattens : into an empty list; so I modified the definition to make () explicitly : slurpy. : : However, that feels wrong, as I'd like to distinguish from a slurpy : nullnary (something that can take a list, as long as it's empty) and a : non-slurpy nullary (something that takes no arguments whatsoever). Right, it's the anchoring problem--but it's really only a problem for compile time typing, and documenting your intent. At run time we know perfectly well that there are 0 arguments. : I have been wondering whether something like : : quicksort( *[] ) : : Can mean a slurpy nullnary, but I failed to find relevant text in : Synopses, so here I am. :-) No, that'd mean a single array reference that has to be empty. : (PS. Yes, I understand that I can use array unpacking and have : quicksort always take a single array argument, but I'd still like to : inquire about slurpy nullary...) If we decide we need to declare non-anchoring intent (and I'm not convinced we do), then maybe the final (or only) arg of a multi can be declared as bare * to indicate it's not anchored to the end of the argument list. But the () declaration indicates already that the function will never match a non-null list, and people might take (*) to mean that it matches a non-null list and throws away the result. So I think your initial solution is actually the right one from the viewpoint of the Perl programmer. If we need to tweak something, it's perhaps to document the fact that *$x is required to match an argument, while [EMAIL PROTECTED] isn't required to match any arguments at all. So if you had multi sub quicksort ( ) { () } multi sub quicksort ( [EMAIL PROTECTED] ) { then when dispatching 0 arguments you actually have an ambiguity that either has to be illegal or solved by ordered matching. I think ordered matching is more conducive to a Prolog-like mentality, and more fail-soft, and slightly righter for Perl. (But that doesn't say much about ordering across different modules, does it?) Larry