[Python-ideas] + operator on generators

Brendan Barnwell brenbarn at brenbarn.net
Tue Jun 27 14:17:44 EDT 2017


On 2017-06-27 00:47, David Mertz wrote:
> Maybe if you are confident a and b are exactly NumPy arrays it is
> obvious, but what about:
>
>      from some_array_library import a
>      from other_array_library import b
>
> What do you think `a & b` will do under your proposal? Yes, I understand
> it's deterministic... but it's far from *obvious*.  This isn't even
> doing something pathological like defining both `.__iter__()` and
> `.__and__()` on the same class... which honestly, isn't even all that
> pathological; I can imagine real-world use cases.

	Hmmm, is the proposal really meant to include behavior that global and 
non-overridable?  My understanding was that the proposal would 
effectively be like defining a default __and__ (or whatever) on some 
basic iterator types.  Individual iterables (or iterators) could still 
define their own magic methods to define their own behavior.  Because of 
that, I wouldn't expect it to be obvious what would happen in your case. 
  If I import types from two random libraries, I can't expect to know 
what any operator does on them without reading their docs.

	Also because of that, I think it might be a bit much to expect this new 
concat operator to work on ALL iterables/iterators/  Nothing else really 
works that way; types have to define their own operator behavior. 
Iterators can be instances of any class that defines a __next__, so I 
don't see how we could support the magic-concat-everything operator 
without interfering there.

	So. . . wouldn't it be somewhat more reasonable to define this concat 
operator only on actual generators, and perhaps instances of the common 
iterator types returned from zip, enumerate, etc.?  Someone earlier in 
the thread said that would be "weird" because it would be less generic 
than itertools.chain, but it seems to me it would cover most of the 
needed use cases (including the one that was initially given as a 
motivating example).  Also, this generator.__add__ could be smart about 
handling other iterables on the right of the operator, so you could do

(x for x in blah) + [1, 2, 3] + "hello"

. . .and, as long as you started with a regular generator, it could 
work, by having the magic method return a new instance of a type that 
also has this behavior.

	This would be a bit odd because I think most existing Python types 
don't try to do this kind of thing (subsuming many different types of 
right-operands).  But I think it would be useful.  In the interim, it 
could be played with by just making a class that implements the __add__ 
(or whatever), so you could do

cool_iterator(x for x in blah) + [1, 2, 3] + "hello"

. . . and just wrapping the leftmost operand would be enough to give you 
nice syntax for chaining all the rest.

-- 
Brendan Barnwell
"Do not follow where the path may lead.  Go, instead, where there is no 
path, and leave a trail."
    --author unknown


More information about the Python-ideas mailing list