Perl

NAVIGATION
CATEGORIES
REFERRENCE
LINKS
  • reduce metaoperator

    8 answers - 883 bytes - related search similar search Add To My Delicious Add To My Stumble Upon Add To My Google Mark Add To My Facebook Add To My Digg Add To My Reddit

    Thu, 5 May 2005, David Wheeler wrote:
    I can see how to ask for a binary (hence infix) operator, but how
    do I ask
    for a prefix or postfix operator specifically, which +<< and do?
    Maybe there are ::Prefix, etc, roles defined so you can ask
    for
    them?
    Ask for them for what?
    For negating all elements of an array:
    @negatives = - @positives;
    They should write them [metaoperators] only for infix operators.
    The above example is in S03, so that is not an option.
    Because [] applies only to infix operators, as I understand it.
    You understand it. I understand it. But how does the parser know the
    difference between
    @x = -<< @y;
    and
    @x = [+] @y;
    or even
    @x -= @y;
    which shows that the position of metaoperator is not the distinguishing
    factor.
  • No.1 | | 1284 bytes | |

    If I understand correctly, so far we have the following meta-operators:

    [ ]
    circumfix meta-operator on infix operator which produces a prefix operator

    ><<

    circumfix meta-operator on infix operator which produces an infix operator

    =
    postfix meta-operator on infix operator which produces an infix operator

    >>

    prefix meta-operator on postfix operator which produces a postfix operator

    <<
    postfix meta-operator on prefix operator which produces a prefix operator

    In other words:

    | Meta-op | is | operates on | to produce |

    | [ ] | circumfix | infix | prefix |

    | ><< | circumfix | infix | infix |

    | = | postfix | infix | infix |

    | >| prefix | postfix | postfix |

    | << | postfix | prefix | prefix |

    From this table, we can see that [ ] is the only meta-operator that
    produces a different 'type' of operator from that which it accepts,
    which might be where the confusion lies. As long as each meta-operator
    explicitly knows what type of regular operator it accepts (and
    produces), there shouldn't be any problems with ambiguity.
  • No.2 | | 2340 bytes | |

    5/5/05, Stuart Cook <scook0 (AT) gmail (DOT) comwrote:

    | 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, *@list is copy) {
    my $r=@list.shift;
    while(@list) {
    $r = block($r, *@list.shift( :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[09; reduce[;](@dims); 09]

    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, let's face it, is likely to
    be the most common use for this'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);
    }
  • No.3 | | 1343 bytes | |

    5/6/05, Stuart Cook <scook0 (AT) gmail (DOT) comwrote:
    (snip) As long as each meta-operator
    explicitly knows what type of regular operator it accepts (and
    produces), there shouldn't be any problems with ambiguity.

    Having posted that, I immediately thought of some problems:

    If a meta-operator has
    {meta-fixity =prefix|circumfix, result-fixity =prefix}
    then it can be confused with a term, e.g.:

    $x = [+1, -2, +3]; # opening [ indicates a term
    $y = [+] @stuff; # opening [ indicates a meta-op producing a prefix operator

    This might confuse the parser, though I suppose you could always try
    both possibilities and see which one works.

    The second problem is if a meta-operator has
    {meta-fixity =postfix, argument-fixity =x, result-fixity =y}
    where (x != y).

    # Imagine '◎' is a meta-postfix taking an infix and and returning a prefix.
    # The parser will reject ¥, because it doesn't know to expect
    # an infix op until it reaches the ◎.
    @x = ¥◎ @z;
    # The parser might assume that + is prefix (since a term is expected),
    # then have to go back and treat it as an infix instead.
    $x = +◎ $z;

    This will /really/ confuse the parser, and should probably (IM) be outlawed.

    Stuart
  • No.4 | | 1565 bytes | |

    5/6/05, Brent 'Dax' Royal-Gordon <brentdax (AT) gmail (DOT) comwrote:
    I find this table very interesting, in that it shows the fundamental
    difference between reduce and the existing meta-ops.

    Yep, that was basically the whole point of the table.

    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.

    I was thinking of restricting the ways in which meta-ops can alter the
    syntax of an op, but now I think we're better off not letting it
    happen at all. Meta-ops that redefine syntax would be very hairy for
    the compiler (as I pointed out), and probably wouldn't buy us much
    that you couldn't achieve with a macro anyway.

    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[09; reduce[;](@dims); 09]

    I personally like that, and it has the additional property of avoiding
    the "[+] @foo" vs. "[+1, -2]" ambiguity I pointed out.

    Furthermore, it makes it /much/ easier for newbies to figure out what
    that code actually does (since they can just grep for 'reduce' in the
    docs).

    Stuart
  • No.5 | | 1412 bytes | |

    Fri, May 06, 2005 at 12:23:49PM +1000, Stuart Cook wrote:
    5/6/05, Stuart Cook <scook0 (AT) gmail (DOT) comwrote:
    (snip) As long as each meta-operator
    explicitly knows what type of regular operator it accepts (and
    produces), there shouldn't be any problems with ambiguity.

    Having posted that, I immediately thought of some problems:

    If a meta-operator has
    {meta-fixity =prefix|circumfix, result-fixity =prefix}
    then it can be confused with a term, e.g.:

    $x = [+1, -2, +3]; # opening [ indicates a term
    $y = [+] @stuff; # opening [ indicates a meta-op producing a prefix operator

    This might confuse the parser, though I suppose you could always try
    both possibilities and see which one works.

    It might not be a problem -- I'm thinking we may end up tokenizing
    most or all of the meta operators, so that [+] would be considered
    its own token, and then the "longest matching token" rule
    would be sufficient to disambiguate the terms:

    $x = [+1, -2, +3]; # token [ indicates a term
    $y = [+] @stuff; # token [+] indicates a meta-op prefix operator

    , the entry for the reduce meta operator might look something like

    %prefixmetaops[ rx / \[ %infixops \] / ] =

    in which case the parser would still be able to easily disambiguate
    the differences when it's expecting an operator.

    Pm
  • No.6 | | 601 bytes | |

    5/7/05, Patrick R. Michaud <pmichaud (AT) pobox (DOT) comwrote:
    It might not be a problem -- I'm thinking we may end up tokenizing
    most or all of the meta operators, so that [+] would be considered
    its own token, and then the "longest matching token" rule
    would be sufficient to disambiguate the terms:

    $x = [+1, -2, +3]; # token [ indicates a term
    $y = [+] @stuff; # token [+] indicates a meta-op prefix operator

    Does that mean postfix meta-ops that modify syntax become possible?
    (Not necessarily a good idea, mind you, but possible)

    Stuart
  • No.7 | | 1874 bytes | |

    Sat, May 07, 2005 at 05:11:19PM +1000, Stuart Cook wrote:
    : 5/7/05, Patrick R. Michaud <pmichaud (AT) pobox (DOT) comwrote:
    : It might not be a problem -- I'm thinking we may end up tokenizing
    : most or all of the meta operators, so that [+] would be considered
    : its own token, and then the "longest matching token" rule
    : would be sufficient to disambiguate the terms:
    :
    : $x = [+1, -2, +3]; # token [ indicates a term
    : $y = [+] @stuff; # token [+] indicates a meta-op prefix operator
    :
    : Does that mean postfix meta-ops that modify syntax become possible?
    : (Not necessarily a good idea, mind you, but possible)

    Vaguely. could imagine for instance a hyper variant that says
    "do this to yourself", and this could force interpretation of the preceding
    operator as an infix operator rather than a unary. So despite the
    fact that there's a unary *, this

    @squares = * @list;

    could be the same as

    @squares = @list * @list

    I'm inclined to agree that it's not a terribly good idea to have
    a metaoperator that does retroactive violence to the meaning of
    an operator. (Note that + doesn't actually change the meaning of
    the +.)

    the other hand, since we've distinguished hyperops on infixes from
    hyperops on unaries, maybe an infix hyperop in unary position just
    does the thing to itself:

    @squares = * @list;

    which gives us a sum-of-squares that looks like this:

    @sumofsquares = [+] * @list;

    That'sinterestingand it doesn't retroactively change the meaning
    of *, since it's got the out front, which currently has no meaning
    when a term is expected, unless I'm going completely senile. Every day
    it gets a little harder to distinguish my senility from my insanity

    Larry
  • No.8 | | 802 bytes | |

    Sat, May 07, 2005 at 01:00:08PM -0700, Larry Wall wrote:
    : the other hand, since we've distinguished hyperops on infixes from
    : hyperops on unaries, maybe an infix hyperop in unary position just
    : does the thing to itself:
    :
    : @squares = * @list;
    :
    : which gives us a sum-of-squares that looks like this:
    :
    : @sumofsquares = [+] * @list;

    the gripping hand, I can't think of any other operators I'd be likely
    to want to do that to, so forget it. Not worth teaching people. Let's
    stick with

    @sumofsquares = [+] @list * @list;

    I'm sure the optimizer can be smart enough to recognize that, if we need
    to optimize it. Should probably recognize

    @sumofsquares = [+] @list ** 2

    as well.

    Larry

Re: reduce metaoperator


max 4000 letters.
Your nickname that display:
In order to stop the spam: 7 + 6 =
QUESTION ON "Perl"

EMSDN.COM