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

Weirdness when mixing `..` and `...` without parens #6021

Open
p6rt opened this issue Jan 20, 2017 · 8 comments
Open

Weirdness when mixing `..` and `...` without parens #6021

p6rt opened this issue Jan 20, 2017 · 8 comments
Labels

Comments

@p6rt
Copy link

@p6rt p6rt commented Jan 20, 2017

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

Searchable as RT130604$

@p6rt
Copy link
Author

@p6rt p6rt commented Jan 20, 2017

From @smls

When the operators `..` and `...` are used in the same comma-separated
list, without disambiguating parentheses, the results are weird​:

  ➜ say 1..2,7,5...2;
  (1..2)

  ➜ say 1..1,7,5...2;
  (1..1 7 5 4 3 2)

  ➜ say 1,7,5...2;
  Unable to deduce arithmetic or geometric sequence from 1,7,5 (or
did you really mean '..'?)
  in block <unit> at -e line 1

Of those examples, the only one that outputs what I expected, is the third one.
What is even going on in the other two?

@p6rt
Copy link
Author

@p6rt p6rt commented Jan 20, 2017

From @AlexDaniel

It numifies ranges so that the number of elements is used. In other words, 1..2 works like 2 and 1..1 works like 1.

It looks like it hurts when you do this…

On 2017-01-20 07​:29​:03, smls75@​gmail.com wrote​:

When the operators `..` and `...` are used in the same comma-separated
list, without disambiguating parentheses, the results are weird​:

➜ say 1..2,7,5...2;
(1..2)

➜ say 1..1,7,5...2;
(1..1 7 5 4 3 2)

➜ say 1,7,5...2;
Unable to deduce arithmetic or geometric sequence from 1,7,5 (or
did you really mean '..'?)
in block <unit> at -e line 1

Of those examples, the only one that outputs what I expected, is the
third one.
What is even going on in the other two?

@p6rt
Copy link
Author

@p6rt p6rt commented Jan 20, 2017

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

@p6rt
Copy link
Author

@p6rt p6rt commented Jan 21, 2017

From @smls

It numifies ranges so that the number of elements is used. In other
words, 1..2
works like 2 and 1..1 works like 1.

No, if it worked like that then the first two examples would throw the same error as the third, instead of exhibiting behaviors that are both different from that and from each other.

Here are two more examples, showing the difference in case of an actual arithmetic series​:

  ➜ say 1..1, 3 ... 7;
  (1..1 3 4 5 6 7)

  ➜ say 1, 3 ... 7;
  (1 3 5 7)

@p6rt
Copy link
Author

@p6rt p6rt commented Aug 26, 2017

From @smls

This bug is still present in

  Rakudo version 2017.08-8-g753c9a5ea built on MoarVM version 2017.08.1-19-g151a2563
  implementing Perl 6.c.

@p6rt
Copy link
Author

@p6rt p6rt commented Aug 26, 2017

From @AlexDaniel

Indeed, I'm not sure what I was smoking.
On 2017-01-20 21​:27​:50, smls75@​gmail.com wrote​:

It numifies ranges so that the number of elements is used. In other
words, 1..2
works like 2 and 1..1 works like 1.

No, if it worked like that then the first two examples would throw the
same error as the third, instead of exhibiting behaviors that are both
different from that and from each other.

Here are two more examples, showing the difference in case of an
actual arithmetic series​:

➜ say 1..1, 3 ... 7;
(1..1 3 4 5 6 7)

➜ say 1, 3 ... 7;
(1 3 5 7)

@p6rt
Copy link
Author

@p6rt p6rt commented Oct 2, 2017

From @AlexDaniel

Oh. Maybe it's https://rt-archive.perl.org/perl6/Ticket/Display.html?id=127279 ?

On 2017-08-26 08​:01​:06, alex.jakimenko@​gmail.com wrote​:

Indeed, I'm not sure what I was smoking.
On 2017-01-20 21​:27​:50, smls75@​gmail.com wrote​:

It numifies ranges so that the number of elements is used. In other
words, 1..2
works like 2 and 1..1 works like 1.

No, if it worked like that then the first two examples would throw the
same error as the third, instead of exhibiting behaviors that are both
different from that and from each other.

Here are two more examples, showing the difference in case of an
actual arithmetic series​:

➜ say 1..1, 3 ... 7;
(1..1 3 4 5 6 7)

➜ say 1, 3 ... 7;
(1 3 5 7)

@p6rt
Copy link
Author

@p6rt p6rt commented Oct 5, 2017

From @skids

On Mon, 02 Oct 2017 00​:26​:27 -0700, alex.jakimenko@​gmail.com wrote​:

Oh. Maybe it's https://rt-archive.perl.org/perl6/Ticket/Display.html?id=127279 ?

On 2017-08-26 08​:01​:06, alex.jakimenko@​gmail.com wrote​:

Indeed, I'm not sure what I was smoking.
On 2017-01-20 21​:27​:50, smls75@​gmail.com wrote​:

It numifies ranges so that the number of elements is used. In other
words, 1..2
works like 2 and 1..1 works like 1.

No, if it worked like that then the first two examples would throw the
same error as the third, instead of exhibiting behaviors that are both
different from that and from each other.

Here are two more examples, showing the difference in case of an
actual arithmetic series​:

➜ say 1..1, 3 ... 7;
(1..1 3 4 5 6 7)

➜ say 1, 3 ... 7;
(1 3 5 7)

This may be operating as designed.

First, note that in ..., you are not guaranteed that all the elements in the first list are returned​:

$ perl6 -e 'say 1,2,3,4...3'
(1 2 3)

...as soon as the 3 on the lhs matches the 3 on the rhs, the sequence terminates.

And yes, some of this is due to ranges collapsing to +.elems. The comparison to
the first value of the rhs list is a smart match, to wit​:

$ perl6 -e 'say (4..7) ~~ 4'
True
$ perl6 -e 'say (4..8) ~~ 4'
False

..only a 4-element list smartmatches 4.

So for the above examples here is what is happening​:

1..2,7,5...2; # 1..2 matches 2. Emit it and stop.

1..1,7,5...2; # nothing matches the 2. So we follow the spec...
where we fall under the "they do not look like numbers" clause,
since the range is not a simple number (as an aside, note that
((1..1) - 7) is (6..6))

So we skip doing this​:

"That is, supposing we call the last three numbers C<$a>, C<$b>, and
C<$c>, and then define​:

  $ab = $b - $a;
  $bc = $c - $b;

If C<$ab == $bc> and C<$ab> is not zero, then we deduce an arithmetic
progression determined by the function C<*+$ab>. If C<$ab> is zero,
and the three values look like numbers, then the function is C<*+0>."

...and we do this instead​:

"If they do not look like numbers, then the function selected is either
C<*.succ> or C<*.pred> depending on whether C<$b cmp $c> appears to be
Increasing or Decreasing. If C<cmp> returns Same then an identity
function is assumed."

...$b is 7 and $c is 5, so we call .pred on 5 until we get a result that matches 2.

1,7,5...2; # We have three actual trailing numbers and should be able to deduce a pattern, but cannot.

@p6rt p6rt added the parser label Jan 5, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
1 participant
You can’t perform that action at this time.