Progressing an iterator is a side-effect (a mutation).
Depending how the last iteration is handled, zip(a, b) and zip(b, a) with iterators of different sizes can have different behaviours: if a is shorter than b, a naïve implementation would update b in the zip(b, a) case, but not in the zip(a, b) case.
That reminds me of a lovely paper "How to Add Laziness to a Strict Language Without Even Being Odd" by Wadler and MacQuenn. They use "map" as their running example, but the problem is basically the same.
zip is generally implemented as a functional concept, where the iterators take values from the backing iterable structure "by const &". You can implement a custom mutating zip operation on top of the iterator protocol.
I believe masklinn is talking about whether `zip` consumes an extra element from the longer iterator on the last iteration, when the shorter iterator raises StopIteration. And the behavior might vary depending on the order of the arguments.