Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Order of is assoc and precedence traits matter, but should it? #6663

Open
p6rt opened this issue Jan 12, 2018 · 3 comments
Open

Order of is assoc and precedence traits matter, but should it? #6663

p6rt opened this issue Jan 12, 2018 · 3 comments

Comments

@p6rt
Copy link

p6rt commented Jan 12, 2018

Migrated from rt.perl.org#132713 (status was 'open')

Searchable as RT132713$

@p6rt
Copy link
Author

p6rt commented Jan 12, 2018

From @briandfoy

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
  { ... }

@p6rt
Copy link
Author

p6rt commented Jan 12, 2018

From @zoffixznet

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&#8203;:\<↑> \( Int&#8203;:D \\n, Int&#8203;:D \\m  \-\-> Int&#8203;:D \)
    is assoc\<right>
    is equiv\(&infix&#8203;:\<\*\*>\)
    \{ 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&#8203;:\<↑> \( Int&#8203;:D \\n, Int&#8203;:D \\m  \-\-> Int&#8203;:D \)
    is equiv\(&infix&#8203;:\<\*\*>\)
    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&#8203;:\<↑> \( Int&#8203;:D \\n, Int&#8203;:D \\m  \-\-> Int&#8203;:D \)
    is equiv\(&infix&#8203;:\<\*\*>\)
    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&#8203;:\<↑>  \( Int&#8203;:D \\n, Int&#8203;:D \\m  \-\-> Int&#8203;:D \)
    is equiv\(&infix&#8203;:\<\*\*>\)
    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] rakudo/rakudo@6f5b27ce63
[2] https://design.perl6.org/S06.html#Subroutine_traits
[3] rakudo/rakudo@f9f0883
[4] Raku/doc#1730

@p6rt
Copy link
Author

p6rt commented Jan 12, 2018

The RT System itself - Status changed from 'new' to 'open'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant