Why can't I `tail` the result of a `tail` on a Perl 6 list?
Asked Answered
I

1

8

Why can't I tail the result of a tail? I can call head on the sequence tail returns (and other variations), but a tail on a tail doesn't work (in 2017.10):

> my $list = <a b c d e f g h i j>;
(a b c d e f g h i j)
> $list.head(5).head
a
> $list.head(5).tail
e
> $list.tail(5).head
f

This one fails:

> $list.tail(5).tail
Nil

But throwing a list in there works:

> $list.tail(5).list.tail
j
Imam answered 7/12, 2017 at 21:51 Comment(5)
It would seem that because tail returns a Seq type and Seq does not have a tail method on it, you must first convert it to a list (either with .list or .List) before you can call the subsequent tail method on it. But it doesn't make sense why it works for head...Gringo
I just tried $list.tail(5).tail(1) and it works, but just not with $list.tail(5).tail. Why does the default parameter not work in the second case?Gringo
Thanks for catching up to my question ;)Imam
.tail and .tail(1) are implemented with Rakudo::Iterator.LastValue and Rakudo::Iterator.LastNValues respectively, which differ quite a bit in implementation. github.com/rakudo/rakudo/blob/master/src/core/Rakudo/… - here's the problematic one.Armitage
i figured out what's wrong: tail on the List takes an iterator and skips it ahead $n items. then, the tail method on Seq calls count-only on it to figure out how far to skip ahead to get the last $m items. However, count-only on the first iterator just gives you the total number of items in the original list. It should probably either signal an error when asked for count-only, or it should calculate the proper amount of items left.Armitage
F
8

This is a bug.

The .count-only optimization method for List.iterator did not account for the fact that the iterator may already be partially consumed (here, by the first .tail call) when the method is called and, as timotimo++ pointed out in the comments, kept always returning the original length. The argless .tail then used that method, hitting the bug.

This is now fixed on 2017.11-76-gf70e20b Rakudo

Unless I'm misunderstanding iterator protocol, the same bug was present in quite a few other iterators, so thanks for finding this hive!

Fleecy answered 8/12, 2017 at 1:59 Comment(1)
Further fixes in 0e228fab8a0b6e91f001 and 854c10c27e49041c87841Sweeper

© 2022 - 2024 — McMap. All rights reserved.