On Fri, 12 Jan 2018 00:02:34 -0800, comdog wrote: > I originally asked this on StackOverflow: > > https://stackoverflow.com/q/48219788/2766176 > > This fails 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) ); > > Reversing the traits fixes that: > > sub infix:<↑> ( Int:D \n, Int:D \m --> Int:D ) > is equiv(&infix:<**>) > is assoc<right> > { n ** m } > > I didn't see anything in the docs about the ordering of traits but > I wouldn't expect order to matter. Neither did I see anything saying I > couldn't combine traits. > > As far as I can tell the precedence still works when it's specified first: > > sub infix:<↑> ( Int:D \n, Int:D \m --> Int:D ) > is equiv(&infix:<**>) > is assoc<right> > { n ** m } > > put "2↑3**4↑2 = ", 2↑2**2↑2; > put "2↑(3**(4↑2)) = ", 2↑2**2↑2; > > > put "2↑3*4↑2 = ", 2↑2*2↑2; > put "(2↑2)*(2↑2) = ", (2↑2)*(2↑2); > > > put "2↑3+4↑2 = ", 2↑2+2↑2; > put "(2↑2)+(2↑2) = ", (2↑2)+(2↑2); > > How is this supposed to work? Should either way work? I can easily > imagine situations where I want to stack many traits: > > sub infix:<↑> ( Int:D \n, Int:D \m --> Int:D ) > is equiv(&infix:<**>) > is assoc<right> > is pure > is export > { ... }
I pushed a fix to a branch[^1] as it appears to be blocked by RT#132711. More precisely, the fix fixes `is equiv` to *copy* associativity (per speculation[^2] and original[^3] behaviour). So in your code that would make it work right only on accident as `&infix:<**>` is right-associative. I also opened a doc issue to document that is equiv/tighter/looser set associativity as well as precedence. [1] https://github.com/rakudo/rakudo/commit/6f5b27ce63 [2] https://design.perl6.org/S06.html#Subroutine_traits [3] https://github.com/rakudo/rakudo/commit/f9f0883c6cef3695c5150d336f5e6552e1be4a4c [4] https://github.com/perl6/doc/issues/1730