#can we not iterate two iterators together in the while syntax?
1 messages · Page 1 of 1 (latest)
the reason that it’s not allowed is that it’s: A, very rare, and B, leads to footguns because now itll stop iterating as soon as one of them returns null and if one of them returned data and the other didnt, you now can’t get that data back ever
just do
while (true) {
const my_path_part = my_path_it.next() orelse break;
const path_part = path_it.next() orelse break;
}
if thats what you want
yep that's where i thought i'd head next. thanks!
But it is not considered a source of footguns with for loops. What's different here?
the data you iterate over in for loops is always there, it doesnt just go missing
with iterators, if you discard an item, that’s gone unless you re-iterate the entire thing again
and you cant even do that sometimes
I'm not sure I fully buy that argument, because similar problems exist even in iterating over a single sequence of items, but okay.
I really dont see that
Well, you can discard the item you are currently iterating over, which would break your next() call (depending on the iterator implementation).
And this situation is not contrived, actually it's somewhat common.
actually looking at the langauge reference, all arrays/slices you iterate over in for loops must be the same length as eachother (and that’s checked at compile time and runtime)
that was my whole point - why doesn't while loop allow the same
that obviously cant be checked for iterators though
IMHO it obviously can be checked - you panic if both iterators do not expire simultaneously
that would be very late
it’s defined as UB but won’t be checked unless the entire iteration completes
so if you have an early exit every time, that would be still be UB but it would never be caught
Fair point, but then I'm not 100% sure it's really a problem. Anyway, not too important.
not really; the next call can require arbitrarily complex or expensive computation, or even have side effects, whilst all the for loop is doing is slice[i]
by discarding the capture, all you're discarding is the result of slice[i], which you can even easily recover
and unlike while iteration, it can be checked ahead of time, meaning there actually can't be a failure during iteration from the loop itself
the only slim circumstance in which you would fail would be a segmentation fault if you were to iterate out of bounds across a page boundary
why can't it be checked? isn't that what you'd use .peek() for?
you can't check if an iterator is the same length as another
well you can, but zig can't do that for you
ah true
an iterator is not a bespoke interface of the language or anything
an iterating function needn't even be called next
and like I said, it could be any arbitrarily complex calculation
many iterators are more generators than they are purely iterators over data
yes, i'm still soaking some of these details in
what you probably want is a call to std.mem.eql
yep i've got a couple of working versions now. haven't put this one through its paces yet but i think it's good
fn splittyStartsWith(haystack: *std.mem.SplitIterator(u8, .scalar), needle: *std.mem.SplitIterator(u8, .scalar)) bool {
while (haystack.next()) |haystack_item| {
if (needle.next()) |needle_item| {
if (!std.mem.eql(u8, haystack_item, needle_item)) {
return false;
}
} else {
return false;
}
}
return true;
}
ah no it's not. needs some tweaks
i did a version where i convert the SplitIterators to arrays of slices that's working but i'm gonna try to finish the above one too
uuuuuh what
that's not what I meant
why can't you just std.mem.startsWith(u8, "/some/path/here/", thing)?
because of how the code around it works. i have to split the paths anyway. but yeah i'm experimenting with a version with std.mem.startsWtih too now that i have a known working version
I think another issue is that what if you don't want them to expire at the same time
If you want one to remain going and keep the other as null then you're going to have to implement it yourself
Then you can ask the same question about the for loops as well, so it'd be a more drastic change to the language.