yoleaux | AlexDaniel`: RT/GH weekly | 07:18 | |||||||||||||||||||||||||||||||||||||
AlexDaniel | yoleaux: No! | 07:19 | |||||||||||||||||||||||||||||||||||||
reportable6: list | |||||||||||||||||||||||||||||||||||||||
reportable6 | AlexDaniel, gist.github.com/877cbb494b57bfaa67...bc70bedf1f | ||||||||||||||||||||||||||||||||||||||
lizmat | . | 11:56 | |||||||||||||||||||||||||||||||||||||
yoleaux | 8 Dec 2017 13:32Z <Zoffix> lizmat: Yeah, my patch changed .count-only to be "how many can you produce". The original semantic of total is kinda pointless isn't it? Unless, I keep track and know for sure the iterator has never been iterated yet, I can't use that method. That's exactly was the reason for the bug in .tail(5).tail; if .count-only doesn't actually indicate the number of elements the iterator will produce, we can't | ||||||||||||||||||||||||||||||||||||||
8 Dec 2017 13:33Z <Zoffix> lizmat: use it to perform the optimization | |||||||||||||||||||||||||||||||||||||||
lizmat | .ask Zoffix why is the original count-only / bool-only semantic pointless? e.g. in a case like "if ^10 .Seq { say "foo" }", it wouldn't need to produce anything | 18:56 | |||||||||||||||||||||||||||||||||||||
yoleaux | lizmat: I'll pass your message to Zoffix. | ||||||||||||||||||||||||||||||||||||||
[TuxCM] |
|
19:25 | |||||||||||||||||||||||||||||||||||||
Zoffix | . | 19:26 | |||||||||||||||||||||||||||||||||||||
yoleaux | 18:02Z <patrickz> Zoffix: Big thumbs up for the containers advent post. It finally got containers into my head. I really liked that it started *without* containers and thus gave context to containers. | ||||||||||||||||||||||||||||||||||||||
18:56Z <lizmat> Zoffix: why is the original count-only / bool-only semantic pointless? e.g. in a case like "if ^10 .Seq { say "foo" }", it wouldn't need to produce anything | |||||||||||||||||||||||||||||||||||||||
Zoffix | lizmat: how will that `if` optimization know that the iterator it's calling .bool-only has never been iterated? | ||||||||||||||||||||||||||||||||||||||
Never been .pull-one'd from or .skip-one, or .skip-at-least, or .push-all. It's mandatory that none of those were ever called for .count-only/.bool-only values to be usable. | 19:27 | ||||||||||||||||||||||||||||||||||||||
Yet, if they were, there's no built-in way to check if they were, so you would get the same .count-only value but there's no guarantee it's accurate. | 19:28 | ||||||||||||||||||||||||||||||||||||||
Whereas with my new semantic, you don't need to care about that detail. You can always call .count-only/.bool-only. Including in your example. | |||||||||||||||||||||||||||||||||||||||
A question for the old semantic is: why is it useful that .count-only stays static? Why is it useful that `if $some-iterable { say "foo" }` would continue to be true, even if it can't pull any more elements? | 19:29 | ||||||||||||||||||||||||||||||||||||||
I mean, other that the obvious: you don't need to keep adjusting it. But why is it useful from the user's end. | 19:30 | ||||||||||||||||||||||||||||||||||||||
c: 2017.11,HEAD if (1, 2, 3, 4, 5, 6).skip(6) { say "w00t" } | 19:46 | ||||||||||||||||||||||||||||||||||||||
committable6 | Zoffix, Ā¦2017.11: Ā«w00tā¤Ā» Ā¦HEAD(1dbf5f5): Ā«Ā» | ||||||||||||||||||||||||||||||||||||||
Zoffix | .tell lizmat here's the example with `if` you showed. It's actually busted due to .count-only not being updated: `c: 2017.11 if (1, 2, 3, 4, 5, 6).skip(6) { say "w00t" }` There are no elements in the iterable, yet it goes through as True | 19:47 | |||||||||||||||||||||||||||||||||||||
yoleaux | Zoffix: I'll pass your message to lizmat. | ||||||||||||||||||||||||||||||||||||||
Zoffix | Got a bug on HEAD too though. Eventually .count-only becomes -1 | 19:48 | |||||||||||||||||||||||||||||||||||||
lizmat | . | 19:49 | |||||||||||||||||||||||||||||||||||||
yoleaux | 19:47Z <Zoffix> lizmat: here's the example with `if` you showed. It's actually busted due to .count-only not being updated: `c: 2017.11 if (1, 2, 3, 4, 5, 6).skip(6) { say "w00t" }` There are no elements in the iterable, yet it goes through as True | ||||||||||||||||||||||||||||||||||||||
lizmat | not convinced it is the correct solution... investigating now | ||||||||||||||||||||||||||||||||||||||
Zoffix | ĀÆ\_(ć)_/ĀÆ to me the new semantics seem a clear winner. And we even have 2 separate core bugs to back up the fragility of the old semantics. | 19:51 | |||||||||||||||||||||||||||||||||||||
and I guess 1 bug to show fragility of new semantics | 19:53 | ||||||||||||||||||||||||||||||||||||||
Zoffix writes test to weed out all the got broken | |||||||||||||||||||||||||||||||||||||||
looks like 4 | 19:59 | ||||||||||||||||||||||||||||||||||||||
lizmat | Zoffix: grokking the issue finally... looks like your approach is indeed the best, the alternative would be to have things like .skip return a new Seq with an alternate iterator, which would be wasteful | 20:06 | |||||||||||||||||||||||||||||||||||||
Zoffix | yeah | ||||||||||||||||||||||||||||||||||||||
jnthn | m: my $a = (^10).iterator; my $b = $a.skip(3); my $c = $a.skip(4); say @(rand > 0.5 ?? $b !! $c) | 20:29 | |||||||||||||||||||||||||||||||||||||
camelia | No such method 'skip' for invocant of type '<anon|145269328>'. Did you mean any of these? Slip skip in block <unit> at <tmp> line 1 |
||||||||||||||||||||||||||||||||||||||
jnthn | m: my $a = (^10).Seq; my $b = $a.skip(3); my $c = $a.skip(4); say @(rand > 0.5 ?? $b !! $c) | 20:30 | |||||||||||||||||||||||||||||||||||||
camelia | (7 8 9) | ||||||||||||||||||||||||||||||||||||||
jnthn | ^ bug, while we're at this | ||||||||||||||||||||||||||||||||||||||
Surely that should be evaluating to 3..9 or 4..9 | 20:31 | ||||||||||||||||||||||||||||||||||||||
(expanded of course, just lazy :)) | |||||||||||||||||||||||||||||||||||||||
Zoffix | m: my $a = (^10).Seq; my $b = $a.skip(3); my $c = $a.skip(4); say @$a | ||||||||||||||||||||||||||||||||||||||
camelia | (7 8 9) | ||||||||||||||||||||||||||||||||||||||
jnthn | That's even wronger :) | 20:32 | |||||||||||||||||||||||||||||||||||||
lizmat | ok, so you're saying that .skip should create a new Seq ? | ||||||||||||||||||||||||||||||||||||||
jnthn | Absolutely. | ||||||||||||||||||||||||||||||||||||||
All potentially lazy operations should. | |||||||||||||||||||||||||||||||||||||||
Otherwise we'll get issues like the above. | |||||||||||||||||||||||||||||||||||||||
Zoffix | This is weird: | ||||||||||||||||||||||||||||||||||||||
m: my $a = (^10).Seq; my $b = $a.skip: 9; say @$a | |||||||||||||||||||||||||||||||||||||||
camelia | (9) | ||||||||||||||||||||||||||||||||||||||
Zoffix | m: (my $a = (^10).Seq).skip: 9; say @$a | 20:33 | |||||||||||||||||||||||||||||||||||||
camelia | This Seq has already been iterated, and its values consumed (you might solve this by adding .cache on usages of the Seq, or by assigning the Seq into an array) in block <unit> at <tmp> line 1 |
||||||||||||||||||||||||||||||||||||||
Zoffix | Ah, .sink-all nevermind | ||||||||||||||||||||||||||||||||||||||
jnthn | Yeah | ||||||||||||||||||||||||||||||||||||||
lizmat | jnthn: but if .skip should create a new Seq, with an iterator that skips N values, you would only be able to do that by cloning the iterator, which would mean you would have to have inside knowledge, or a .clone method on each iterator ? | 20:36 | |||||||||||||||||||||||||||||||||||||
Zoffix | I would've thought it'd steal the iterator from original Seq | 20:37 | |||||||||||||||||||||||||||||||||||||
lizmat | yeah, but then you would still have the same issue | ||||||||||||||||||||||||||||||||||||||
Zoffix | So the second .skip would say "Seq already comsued" | ||||||||||||||||||||||||||||||||||||||
lizmat | m: my $a = (^10).Seq; my $b = $a.skip(3); my $c = $a.skip(4); say @$a # would not prevent this | 20:38 | |||||||||||||||||||||||||||||||||||||
camelia | (7 8 9) | ||||||||||||||||||||||||||||||||||||||
Zoffix | No, they'd be no way to have 3 different Seqs all using the same iterator. | ||||||||||||||||||||||||||||||||||||||
^ that would throw Seq consumed on second .skip call, as well as on @$a | |||||||||||||||||||||||||||||||||||||||
lizmat | then the term "consumed" is incorrect, as it may not have done anything on it | 20:40 | |||||||||||||||||||||||||||||||||||||
"iterator already in use by another Seq" may be more appropriate then | |||||||||||||||||||||||||||||||||||||||
jnthn | method skip($n) { gather { my $i = self.iterator; my $end; for ^$n { if $i.pull-one =:= IterationEnd { $end = True; last; } }; unless $end { until (my \v = $i.pull-one) =:= IterationEnd { take v } } } } | 20:41 | |||||||||||||||||||||||||||||||||||||
skip needn't be implemented like that, but the semantics should be as if it were | |||||||||||||||||||||||||||||||||||||||
Zoffix | m: my $a = (^10).Seq; my $b = Seq.new($a.iterator).skip(3); say @$a | 20:42 | |||||||||||||||||||||||||||||||||||||
camelia | This Seq has already been iterated, and its values consumed (you might solve this by adding .cache on usages of the Seq, or by assigning the Seq into an array) in block <unit> at <tmp> line 1 |
||||||||||||||||||||||||||||||||||||||
lizmat | well, apart from the fact that we don't create a new Seq, the semantics *are* already that way afaik, | ||||||||||||||||||||||||||||||||||||||
jnthn | That is, by an iterator that, upon the first time it is pull-one'd, does pull-one $n times and then does it passing on values until iteration end | ||||||||||||||||||||||||||||||||||||||
So .skip adds an iterator onto the chain | |||||||||||||||||||||||||||||||||||||||
And wraps that new iterator in a new Seq | |||||||||||||||||||||||||||||||||||||||
Neither can be in place | |||||||||||||||||||||||||||||||||||||||
lizmat | Zoffix: want me to do that, or will you ? | 20:43 | |||||||||||||||||||||||||||||||||||||
Zoffix | lizmat: you :) I'm still fishing the bugs in .count-only stuff | 20:44 | |||||||||||||||||||||||||||||||||||||
lizmat | ok, will take care of that then :-) | 20:47 | |||||||||||||||||||||||||||||||||||||
jnthn | lizmat++ Zoffix++ | ||||||||||||||||||||||||||||||||||||||
lizmat | fwiw, I don't think they were bugs, just different semantics ? | ||||||||||||||||||||||||||||||||||||||
Zoffix | m: if (1, 2, 3, 4, 5, 6).skip(6) { say "w00t" } | 20:49 | |||||||||||||||||||||||||||||||||||||
camelia | ( no output ) | ||||||||||||||||||||||||||||||||||||||
Zoffix | m: if (1, 2, 3, 4, 5, 6).skip(76) { say "w00t" } | ||||||||||||||||||||||||||||||||||||||
camelia | w00t | ||||||||||||||||||||||||||||||||||||||
Zoffix | ^ there ain't no elements but it still skips, 'cause I messed up and the .pull-one that gives IterationEnd puts the counters to -1, which is true | 20:50 | |||||||||||||||||||||||||||||||||||||
s/still skips/still gives true/; | |||||||||||||||||||||||||||||||||||||||
lizmat | ack | 20:56 | |||||||||||||||||||||||||||||||||||||
brb& | |||||||||||||||||||||||||||||||||||||||
Geth | rakudo: 0e228fab8a | (Zoffix Znet)++ | 2 files Second pass on fixing .count-only/.bool-only issues - Fixes .count-only not updating in Hash.kv iterator - Fixes .count-only/.bool-only returning wrong values when the last .pull-one (the one that gives IterationEnd) is called First pass was done in: github.com/rakudo/rakudo/commit/af...3292723871 |
21:59 | |||||||||||||||||||||||||||||||||||||
roast: 81fdf3f237 | (Zoffix Znet)++ | MISC/bug-coverage.t Improve .count-only/.bool-only tests - Reduce code by dynamically generating iterators to test - Add extra tests for .count-only, for value given after IterationEnd-producing .pull-one is called - Separate .bool-only tests into a separate run and test the values produced during iteration as well as after IterationEnd was produced. Rakudo fix covered by new tests: github.com/rakudo/rakudo/commit/0e228fab8a |
22:02 | ||||||||||||||||||||||||||||||||||||||
rakudo: 854c10c27e | (Elizabeth Mattijsen)++ | src/core/Seq.pm Make sure each Seq.skip gets a new Seq |
22:48 |