On Apr 26, 2020, at 21:23, David Mertz <mertz@gnosis.cx> wrote:
On Sun, Apr 26, 2020 at 11:56 PM Christopher Barker <pythonchb@gmail.com> wrote:
If I have two or more "sequences" there are basically two cases of that.
so you need to write different code, depending on which case? that seems not very "there's only one way to do it" to me.
This difference is built into the problem itself. There CANNOT be only one way to do these fundamentally different things.
With iterators, there is at heart a difference between "sequences that one can (reasonably) concretize" and "sequences that must be lazy." And that difference means that for some versions of a seemingly similar problem it is possible to ask len() before looping through them while for others that is not possible (and hence we may have done some work that we want to "roll-back" in some sense).
Agreed. But here’s a different way to look at it: The Python iteration protocol hides the difference between different kinds of iterables; every iterator is just a dumb next-only iterator. So any distinction between things you can pre-check and things you can post-check has to be made at a higher level, up wherever the code knows what’s being iterated (probably the application level). That isn’t inherent to the idea of iteration, as demonstrated by C++ (and later languages like Swift), where you can have reversible or random-accessible iterators and write tools that switch on those features, so you wouldn’t be forced to make the decision at the application level. You could write a generic C++ zip_equal function that pre-checks random-accessible iterators but post-checks other iterators. But when would you want that generic function? When you’re writing that application code, you know whether you have sequences, inherently lazy iterators, or generic iterables as input, and you know whether you want no check, a pre-check, or a post-check on equal lengths, and those aren’t independent questions: when you want a pre-check, it’s because you’re thinking in sequence terms, not general iteration terms. Pre-checking sequences is so trivial that you don’t need any helpers. The only piece Python is (arguably) missing is a way to do that post-check easily when you’ve decided you need it, and that’s what the proposals in this thread are trying to solve. The fact that asking for post-checking on the zip iterator won’t look the same as manually pre-checking the input sequences isn’t a violation of TOOWTDI because the “it” you’re doing is a different thing, different in a way that’s meaningful to your code, and there doesn’t have to be one obvious way to do two different things. Just like slicing doesn’t have to look the same as islice, and a find method doesn’t have to look the same as a generic iterable find function, and so on; they only look the same when the distinction between thinking about sequences and thinking about lazy iterables is irrelevant to the problem.