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
Ambiguity in slicing with Ranges / WhateverCodes #50
Comments
FWIW I think |
It's not clear to me if you had a potential solution in mind or what it would be. Changing the meaning of About the commit
Which vein do you mean? Does it play on the ambiguity too much or do the changes slow things down? At least it does not introduce an additional check. What I tried to do in that commit is remove the remaining observable difference in slicing with
Before, the last one would actually omit the last element in a slice and I still think this was just an off-by-one bug which was triggered in a corner case¹. If I read About the warning
I'd write verbosely @a[-> $elems { 0 .. $elems-2 }] which becomes @a[0..*-2] # up to the second-to-last element
@a[0..^*-1] # up to and excluding the last element In any case, it's going to be a WhateverCode because BTW, I would also prefer Where is the problem?As I understand it and as you said, the issue involves On the other hand, I do not think that this is a problem with slicing. The only source of ambiguity I see here are the types being sent to the slicer, but you don't want to lose these possibilities, and after rakudo/rakudo@35b69f0 I haven't seen an example where the result is discontinuous when you pass from one type to another by a little change of syntax (as in the list above). Another ambiguityWell, except this one: say (1..10)[0 .. *]; #= (1 2 3 4 5 6 7 8 9 10)
say (1..10)[0 .. *+0]; #= (1 2 3 4 5 6 7 8 9 10 Nil) But the solution to that, IMHO, lies in documentation. ¹ Namely use nqp;
say nqp::eqaddr((0..Inf).max, Inf); #= 1
say nqp::eqaddr((0..*).max, Inf); #= 0 |
I don't have a clear picture on what would be a solution. I see two issues: one is that The other one is that:
There should not be a difference here. Fixing this would fix what rakudo/rakudo@35b69f0 is trying to fix, would it not? |
Agree completely.
No, it would make the first of the two changes in the diff unnecessary. If that commit was reverted entirely and the
I would say the first half of the diff should be reverted as soon as |
On the surface, these two pieces of code do exactly the same thing:
But under the hood, they do very different things.
In the first case, the slice is produced from a
Range
0..^Inf
, so it will just produce values for the slice until the source is exhausted.In the second case, the slice is produced from a
WhateverCode
:Specifically,
^*
codegens as{ ^$_ }
, which is effectively the same as^(*-0)
.So, what does one need to do if one wants to have a slice of all but the last values of a Iterable? Well, this does not do the right thing:
because that's the equivalent of doing:
The next thing one could do, is to use the
*-1
syntax:This does not work, because:
To make this work, one needs to use parentheses:
Issue rakudo/rakudo#3010 indicates that a warning would need to be in place. I'm not sure that that is the correct solution to this situation.
I think part of the underlying issue is the difference in codegen for:
Perhaps we need to change the codegen for
^*
. In any case, any changes here are part of potentially very hot code, so any additional checks will slow things down for all. In that vein, I also think that rakudo/rakudo@35b69f0 should probably be reverted.The text was updated successfully, but these errors were encountered: