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

hyper-op misbehaves when a Range is on the non-magical side of the op #4272

Closed
p6rt opened this issue May 28, 2015 · 4 comments
Closed

hyper-op misbehaves when a Range is on the non-magical side of the op #4272

p6rt opened this issue May 28, 2015 · 4 comments

Comments

@p6rt
Copy link

p6rt commented May 28, 2015

Migrated from rt.perl.org#125265 (status was 'resolved')

Searchable as RT125265$

@p6rt
Copy link
Author

p6rt commented May 28, 2015

From @Util

I tried to translated Perl 5​:
  my %bases=('K' => $base, 'M' => $base**2, 'G'=>$base**3, 'T'=>$base**4);
into both of these in Perl 6​:
  my %bases = <K M G T> Z=> ( $base X** 1..* );
  my %bases = <K M G T> Z=> ( $base <<**<< 1..* );

The cross-op version works.
The hyper-op version gives incorrect output​:
  <Util> m​: my $base = 10; my %bases = <K M G T> Z=> ( $base <<**<< 1..* ); say %bases.perl
  <camelia> rakudo-moar c2a57e​: OUTPUT«{​:G(12), :K(10), :M(11), :T(13)}<>␤»

Removing the interactions of Z=> and Whatever, lead to this simplified bug​:

< Util> m​: say [ 10 <<**<< (1,2,3,4) ].perl;
<+camelia> rakudo-moar c2a57e​: OUTPUT«[10, 100, 1000, 10000]␤»
< Util> m​: say [ 10 <<**<< (1..4) ].perl;
<+camelia> rakudo-moar c2a57e​: OUTPUT«Cannot find method 'Range'␤ in block <unit> at /tmp/nk6UBshobl​:1␤␤»
< Util> ??? Bug?
< masak> Util​: looks like.
< lizmat> repeatable WAT's should be perlbugged :-)
< masak> Util​: please submit.
< Util> lizmat​: Noted. masak​: will do.
< Util> lizmat​: I confess that when I post 2 (working,then non-working) `m​:` on this channel, and ask `bug?`
< Util> I am also secretly asking "is this a *known* bug, that I would already know if I read the channel as much as I should" :^)
< Util> thanks all!
< lizmat> Util​: fwiw, it didn't look familiar to me

Note that the problem persists when `**` is changed to `*`.
The result does change when the range is wrapped in parens.

<Util> m​: say [ 10 <<*<< (1,2,3,4) ].perl;
<camelia> rakudo-moar c2a57e​: OUTPUT«[10, 20, 30, 40]␤»
<Util> m​: say [ 10 <<*<< 1..4 ].perl;
<camelia> rakudo-moar c2a57e​: OUTPUT«[]␤»
<Util> m​: say [ 10 <<*<< (1..4) ].perl;
<camelia> rakudo-moar c2a57e​: OUTPUT«Cannot find method 'Range'␤ in block <unit> at /tmp/NvWvYfUj6y​:1␤␤»

Finally, I do not see the problem when the "magic" pointy-side of the hyper is a range;
the problem only shows up on the non-magic side.
<Util> m​: say (1,2,3,4) >>*>> (2..3);
<camelia> rakudo-moar c2a57e​: OUTPUT«2 6 6 12␤»

--
Thank you,
Bruce Gray (Util of PerlMonks)

@p6rt
Copy link
Author

p6rt commented Oct 24, 2015

From @usev6

One thing to note is that infix​:<**> (and also the hypered version of it) has a tighter precedence than the range operator. Therefore we need parenthesis to get the expected result. (Using a range there works now).

$ perl6-m -e 'say 1 <<**<< (1 .. 4)'
(10 100 1000 10000)

$ perl6 -e 'say 10 <<**<< 1 .. 4'
10..4

$ perl6 -e 'say (10 <<**<< 1) .. 4'
10..4

The thighter precedence was also behind the "incorrect" output of the compound example​:

$ perl6 -e 'my $base = 10; my %bases = <K M G T> Z=> ( $base <<**<< 1..* ); say %bases'
G => 12, K => 10, M => 11, T => 13

... which is the same as

$ perl6 -e 'my $base = 10; my %bases = <K M G T> Z=> ( ($base <<**<< 1) .. * ); say %bases'
G => 12, K => 10, M => 11, T => 13

Using parenthesis around the infinite range fails with X​::HyperOp​::Infinite​:

$ perl6 -e 'my $base = 10; my %bases = <K M G T> Z=> ( $base <<**<< (1 .. *) ); say %bases'
List on right side of hyperop of infix​:<**> is known to be infinite
  in block <unit> at -e​:1

But using a finite range works​:

$ perl6 -e 'my $base = 10; my %bases = <K M G T> Z=> ( $base <<**<< (1 .. 4) ); say %bases'
G => 1000, K => 10, M => 100, T => 10000

I added three tests to S03-metaops/hyper.t with commit Raku/roast@0e4520aff9.

I'm closing this ticket as 'resolved'.

1 similar comment
@p6rt
Copy link
Author

p6rt commented Oct 24, 2015

From @usev6

One thing to note is that infix​:<**> (and also the hypered version of it) has a tighter precedence than the range operator. Therefore we need parenthesis to get the expected result. (Using a range there works now).

$ perl6-m -e 'say 1 <<**<< (1 .. 4)'
(10 100 1000 10000)

$ perl6 -e 'say 10 <<**<< 1 .. 4'
10..4

$ perl6 -e 'say (10 <<**<< 1) .. 4'
10..4

The thighter precedence was also behind the "incorrect" output of the compound example​:

$ perl6 -e 'my $base = 10; my %bases = <K M G T> Z=> ( $base <<**<< 1..* ); say %bases'
G => 12, K => 10, M => 11, T => 13

... which is the same as

$ perl6 -e 'my $base = 10; my %bases = <K M G T> Z=> ( ($base <<**<< 1) .. * ); say %bases'
G => 12, K => 10, M => 11, T => 13

Using parenthesis around the infinite range fails with X​::HyperOp​::Infinite​:

$ perl6 -e 'my $base = 10; my %bases = <K M G T> Z=> ( $base <<**<< (1 .. *) ); say %bases'
List on right side of hyperop of infix​:<**> is known to be infinite
  in block <unit> at -e​:1

But using a finite range works​:

$ perl6 -e 'my $base = 10; my %bases = <K M G T> Z=> ( $base <<**<< (1 .. 4) ); say %bases'
G => 1000, K => 10, M => 100, T => 10000

I added three tests to S03-metaops/hyper.t with commit Raku/roast@0e4520aff9.

I'm closing this ticket as 'resolved'.

@p6rt p6rt closed this as completed Oct 24, 2015
@p6rt
Copy link
Author

p6rt commented Oct 24, 2015

@usev6 - Status changed from 'new' to 'resolved'

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

No branches or pull requests

1 participant