Python 3000 idea -- + on iterables -> itertools.chain

George Sakkis george.sakkis at gmail.com
Mon Nov 13 16:00:16 CET 2006


Carl Banks wrote:

> George Sakkis wrote:
> > Fredrik Lundh wrote:
> >
> > > George Sakkis wrote:
> > >
> > > > The base object class would be one candidate, similarly to the way
> > > > __nonzero__ is defined to use __len__, or __contains__ to use __iter__.
> > > >
> > > > Alternatively, iter() could be a wrapper type (or perhaps mixin)
> > > > instead of a function, something like:
> > >
> > > so you're proposing to either make *all* objects respond to "+", or
> > > introduce limited *iterator* algebra.
> >
> > If by 'respond to "+"' is implied that you can get a "TypeError:
> > iterable argument required", as you get now for attempting "x in y" for
> > non-iterable y, why not ?
>
> Bad idea on many, many levels.  Don't go there.

Do you also find the way "in" works today a bad idea ?

> > Although I like the iterator algebra idea
> > better.
> >
> > > not sure how that matches the OP's wish for "mostly backwards
> > > compatible" support for *iterable* algebra, really...
> >
> > Given the subject of the thread, backwards compatibility is not the
> > main prerequisite. Besides, it's an *extension* idea; allow operations
> > that were not allowed before, not the other way around or modifying
> > existing semantics.
>
> You missed the important word (in spite of Fredrick's emphasis):
> iterable.  Your iter class solution only works for *iterators* (and not
> even all iterators); the OP wanted it to work for any *iterable*.

I didn't miss the important word, I know the distinction between
iterables and iterators; that's why I said I like the iterator algebra
idea better (compared to extending the object class so that effectively
creates an iterable algebra).

> "Iterator" and "iterable" are protocols.  The only way to implement
> what the OP wanted is to change iterable protocol, which means changing
> the documentation to say that iterable objects must implement __add__
> and that it must chain the iterables, and updating all iterable types
> to do this.  Besides the large amount of work that this will need,
> there are other problems.
>
> 1. It increases the burden on third party iterable developers.
> Protocols should be kept as simple as possible for this reason.
> 2. Many iterable types already implement __add__ (list, tuple, string),
> so this new requirement would complicate these guys a lot.

If __add__ was ever to be part of the *iterable* protocol, it would be
silly to implement it for every new iterable type; the implementation
would always be the same (i.e. chain(self,other)), so it should be put
in  a base class all iterables extend from. That would be either a
mixin class, or object. This is parallel to how __contains__ is part of
the sequence protocol, but if you (the 3rd party sequence developer)
don't define one, a default __contains__ that relies on __getitem__ is
created for you.

> > Of course, programs that attempt forbidden
> > expressions on purpose so that they can catch and handle the exception
> > would break when suddenly no exception is raised, but I doubt there are
> > many of those...
>
> 3. While not breaking backwards compatibility in the strictest sense,
> the adverse effect on incorrect code shouldn't be brushed aside.  It
> would be a bad thing if this incorrect code:
>
> a = ["hello"]
> b = "world"
> a+b
>
> suddenly started failing silently instead of raising an exception.

That's a good example for why I prefer an iterator rather than an
iterable algebra; the latter is too implicit as "a + b" doesn't call
only __add__,  but __iter__ as well. On the other hand, with a concrete
iterator type "iter(a) + iter(b)" is not any more error-prone than
'int(3) + int("2")' or 'str(3) + str("2")'.

What's the objection to an *iterator* base type and the algebra it
introduces explicitly ?

George




More information about the Python-list mailing list