Questions/issues regarding generators

Tab Atkins Jr. jackalmage at gmail.com
Fri Mar 8 15:31:06 PST 2013


On Fri, Mar 8, 2013 at 9:23 AM, Jason Orendorff
<jason.orendorff at gmail.com> wrote:
> On Thu, Mar 7, 2013 at 1:05 PM, Andreas Rossberg <rossberg at google.com>
> wrote:
>> On 7 March 2013 18:30, Allen Wirfs-Brock <allen at wirfs-brock.com> wrote:
>> > Zip's informal contract should state that if iterators are passed as
>> > arguments they need to be distinct objects. If you want to implement it
>> > defensively, you can add a  check for that pre-condition.
>>
>> I have to disagree here. That is just evading the question what the
>> contract for .iterator is. Either it is supposed to create new state
>> or it isn't. It's not a very useful contract to say that it can be
>> both, because then you cannot reliably program against it.
>
> In Python, the contract definitely says that it can be both. It's the only
> practical choice. For collections, you want new state. But you also want
> things such as generators, database cursors, and file descriptors to be
> iterable:
>
>     with open(filename, 'r') as f:
>         for line in f:
>             handle_input(line)
>
> and you definitely don't want new state here, because what would that even
> mean? A read position is kind of inherent to a file descriptor, right?
>
> When you call zip() in Python, you expect that each argument will be
> iterated. I mean, it could hardly be otherwise. So if you've got an argument
> that can only be consumed once (either something like a file, or an
> arbitrary iterable you don't know about), you don't pass it twice; and you
> expect each such argument to become useless afterwards, just as if you had
> used it in a for-loop. That's clear enough to code to reliably in practice.
> It's not all that different from Unix pipes.

And in Python, the iterator algebra has .tee(), which uses caching to
produce multiple copies of a stateful iterator.

~TJ


More information about the es-discuss mailing list