Skip Menu |
Report information
Id: 132713
Status: open
Priority: 0/
Queue: perl6

Owner: Nobody
Requestors: comdog <brian.d.foy [at] gmail.com>
Cc:
AdminCc:

Severity: (no value)
Tag: (no value)
Platform: (no value)
Patch Status: (no value)
VM: (no value)



Date: Fri, 12 Jan 2018 03:01:46 -0500
From: brian d foy <brian.d.foy [...] gmail.com>
Subject: Order of `is assoc` and precedence traits matter, but should it?
To: rakudobug [...] perl.org
Download (untitled) / with headers
text/plain 1.4k
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 { ... }
RT-Send-CC: perl6-compiler [...] perl.org
Download (untitled) / with headers
text/plain 2.2k
On Fri, 12 Jan 2018 00:02:34 -0800, comdog wrote: Show quoted text
> 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


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

For issues related to this RT instance (aka "perlbug"), please contact perlbug-admin at perl.org