Trey Harris wrote:
>> sub repeat is multi ($desc is valued(1), &body) {
>> body(1);
>> }
>>
>> sub repeat is multi ($desc is valued(0), &body) {
>> }
>>
>> sub repeat is multi ($desc is valued(['A'..'F']), &body) {
>> die "Can't repeat hexadecimally";
>
> This is very nice. But ordering of multimethod declarations suddenly
> matters, doesn't it? With simple multimethods based on class structures,
> you use the best match (if the actual argument is Integer, I'll prefer the
> method where the corresponding signature is Integer, then Rational, then
> Real, then Complex), right? But with this mechanism, you just have
> boolean acceptance of the argument, so I assume that ordering will be how
> you decide which multimethod to call--the first to accept its argument
> wins.
I would much prefer to see it still checking all variants (i.e. use exactly
the same multiple dispatch mechanism. By default, a value match would cost
zero, but you could specify the actual cost, just as you can with class-based
multiple dispatch in Perl).
In the case of multiple variants matching, the normal exception would be
thrown (unless there was a default variant).
> Yes. I think it works great as a C<map> replacement. For a C<grep>
> replacement, it's a little unwieldy:
>
> P5:
> @odds = grep { $_ % 2 } @nums;
>
> P6:
> @odds = for @nums { next unless $_ % 2; $_};
Sure. But simple cases like that are what C<grep> is for.
As with C<map>, the C<for>-ish version of C<grep> is better applied when the
block gets nasty:
P5:
@special = grep { is_prime($_) &&
$_**2 % 3 &&
do { @fp1 = factors($_+1);
@fm1 = factors($_-1);
my $intersects;
check: foreach my $fp1 (@fp1) {
foreach my $fm1 (@fm1) {
$intersects =1 and last check
if $fp1 == $fm1;
}
}
$intersects && @fp1>2 && @fm1>2;
}
} @nums;
P6:
@special = for @nums {
next unless is_prime($_) && $_**2 % 3;
@fp1 = factors($_+1);
@fm1 = factors($_-1);
next unless @fp1=~@fm1 && @fp1>2 && @fm1>2;
$_;
}
Damian