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
Errors indexing past the end of a List #160
Comments
From @briandfoyAccessing a List element beyond the end of the List returns Nil, my $list = < a b c >; First, in the "before" case, we have more information than the error { But this requires the change I think is more helpful. Since the List { This would then be the error for assigning into a position beyond the { |
From @AlexDanielHm. Wouldn't that make behavior of Lists and Arrays different? On 2017-07-04 05:29:20, comdog wrote:
|
The RT System itself - Status changed from 'new' to 'open' |
From @lizmat
No, because Lists are supposed to be immutable wrt to the number of elements. That said, a List may not always be completely reified already. So logically, a List may have 100 elements, it could well be that only 42 of these elements exist already. Which means that the underlying NQP array, which *is* mutable, only has 42 elements. But it cannot know offhand whether those are all possible elements, as that depends on the iterator that is being used to fill the NQP array. A complicating factor is that this is a very hot code path, so any changes there could affect general performance significantly. My initial tests to generate a Failure on out of bounds value immediately results in 2 internal errors trying to generate backtrace :-( Anyways, I agree with brian’s feelings on this. The challenge is now to make it so without making everything significantly slower. FWIW, the code in question lives around line 480 in List.pm. Liz |
From @lizmat
An example of a List that will never be fully reified: $ 6 'my $l = ^Inf .list; dd $l.^name; dd $l[10]' Liz |
From @zoffixznetOn Tue, 04 Jul 2017 07:20:50 -0700, elizabeth wrote:
Yes, but that doesn't mean the user of the list necessarily knows or has to know how many elements the list has, to look up an element by index, without things exploding.
IMO that's the wrong approach and the current behaviour of returning Nil is most desirable. Consider this code: sub do-stuff (@args) { do-stuff []; If you Fatalise past-end .AT-POS on Lists that sub will now work fine with Arrays, but crash with Lists. So as a consumer of `@args` Iterable, I'm now faced with two potential behaviours and have to account for Exceptions. Currently, the code will also produce a warning, as do many things that consume a Nil where Nil doesn't really belong. IMO that's a good-enough warning for the inadvertent out-of-bounds access. By adding the Failure, we also end up with another inconsistency that `my ($a, $b) = @list` would work and assign Nil to `$b` when `@list` has just one element, but `my ($a, $b) = @list[0,1]` would assign a Failure to it. Lastly, we'd have `@list[0,1]` return a list with 1 value and 1 Failure in it (call .elems on it and the Failure's silently gone). So, IMO, yes, we could change "0..^Inf" to tell number of actual elements, but that error is fundamentally different from trying to access past List's end, because you can NEVER access element at index -1, yet you can access index N, and we should leave the "return Nil" behaviour as is and not deviate from Array behaviour. |
TL;DR What would be the best behavior for these? my $list = < a b c >;
say $list[- 1]; # note that it needs to be “- 1” and not “-1”
say $list[42]; |
Migrated from rt.perl.org#131699 (status was 'open')
Searchable as RT131699$
The text was updated successfully, but these errors were encountered: