On 5/5/05, Stuart Cook <[EMAIL PROTECTED]> wrote:
> +---------+-----------+-------------+------------+
> | Meta-op | is | operates on | to produce |
> +---------+-----------+-------------+------------+
> | [ ] | circumfix | infix | prefix |
> +---------+-----------+-------------+------------+
> | >> << | circumfix | infix | infix |
> +---------+-----------+-------------+------------+
> | = | postfix | infix | infix |
> +---------+-----------+-------------+------------+
> | >> | prefix | postfix | postfix |
> +---------+-----------+-------------+------------+
> | << | postfix | prefix | prefix |
> +---------+-----------+-------------+------------+
I find this table very interesting, in that it shows the fundamental
difference between reduce and the existing meta-ops.
The existing meta-operators alter the semantics of the opoerator, but
don't really change its syntax; a unary operator is still unary, a
binary operator is still binary, and so on. Reduce is irreducibly
(pardon the pun) different, in that it alters the syntax as well as
the semantics.
My suggestion is simple:
multi *reduce(&block, [EMAIL PROTECTED] is copy) {
my [EMAIL PROTECTED];
while(@list) {
$r = block($r, [EMAIL PROTECTED]( :elems(&block.arity - 1) );
}
return $r;
}
macro *reduce ($op, $expr) is parsed( / \[ (<infix_operator>) \]
(<expr>)/ ) {
# Would be reworked to produce a parse tree
return "reduce(&infix:<$op>, $expr)";
}
That would result in the following syntaxes:
reduce { $^a / $^b } @foo;
reduce [/] @foo;
$sum = reduce[+] @array;
$fact = reduce[*] 1..$num;
$firsttrue = reduce[||] @args;
$firstdef = reduce[//] @args;
@sumrows := reduce[+�] @rows;
@foo[0..9; reduce[;](@dims); 0..9]
Clearly we could squabble about the exact bracketing operators to use
(I chose square brackets because I thought they'd be less ambiguous
than parentheses or curlies), but I trust you get the idea.
I agree that reduce is very useful, and I even agree that it should be
in core, but it's not *so* useful that it needs to be invokable
without a keyword. Summing a list--which, let's face it, is likely to
be the most common use for this--isn't common enough an operation to
need such a compact syntax; I can think of more useful meta-ops, like
one that tags each result with the operands that created it, allowing
junctions to be used for the stuff people currently complain they
can't be.
multi sub *infixmetaop:<[ ]> ( $lhs, $rhs ) {
return call but operands($lhs, $rhs);
}
--
Brent 'Dax' Royal-Gordon <[EMAIL PROTECTED]>
Perl and Parrot hacker