Why is Perl 6's right associativity not right?
Asked Answered
E

1

14

Clickbaity title but it's too meaty to pass up. I have this operator which I want to be right associative:

sub infix:<↑> ( Int:D \n, Int:D \m  --> Int:D )
    is assoc<right>
    is equiv(&infix:<**>)
    { n ** m }

put "2**2**2**2 = ",      2**2**2**2;
put "2↑2↑2↑2 = ",         2↑2↑2↑2;
put "2↑ (2↑ (2↑2) ) = ",  2↑ (2↑ (2↑2) );

It's not right associative:

2**2**2**2 = 65536
2↑2↑2↑2 = 256
2↑ (2↑ (2↑2) ) = 65536

What am I not doing right (ahem)?

Emplacement answered 12/1, 2018 at 4:56 Comment(4)
If we swap lines 2 and 3, everything is OK. 2**2**2**2 = 65536 2↑2↑2↑2 = 65536 2↑ (2↑ (2↑2) ) = 65536. Seems that precedence has higher precedence. :)Cooking
Make that an answer and I can accept that. I just figured that out too by selectively commenting out code.Emplacement
rt.perl.org/Ticket/Display.html?id=132713Emplacement
There's already Zoffix's answer, which thoroughly clarifies the matter. :)Cooking
L
14

Looks like there's a can of bugs here...

First, is assoc in this particular case is not needed. As is equiv copies all the options, not just precedence, and &infix:<**> is right-associative.

The reason it doesn't work is because some guy broke it in Apr. 2017, by having it delete assoc (essentially setting it to left-associate).

I've now reverted that commit, but in a branch because the revert exercises RT#132711, which is what original deletion of assoc tried to fix. I'll give a go in fixing that bug this weekend and then will merge the fix for is equiv. UPDATE: It actually explodes in EXPR parser. My rakudo haxor level isn't high enough to work on that thing yet, so I'll leave it to someone smarter, for now.

P.S.: you can save a few chars by writing infixes as &[**] instead of &infix:<**>

Liebknecht answered 12/1, 2018 at 11:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.