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

Reply via email to