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