Re: [Python-ideas] + operator on generators

On Tue, Jun 27, 2017 at 01:53:37PM -0700, Mike Miller wrote:
On 2017-06-25 20:23, Steven D'Aprano wrote:
I have a counter-proposal: introduce the iterator chaining operator "&":
iterable & iterable --> itertools.chain(iterable, iterable)
I like this suggestion. Here's another color that might be less controversial:
iterable3 = iterable1.chain(iterable2)
That requires every iterable class to add its own reimplementation of chain, or else it will surprisingly not be chainable -- or at least it *sometimes* won't be chainable. chain(iterable1, iterable2) would be more acceptable. The reason why a function would be better here than a method is explained in the FAQ for why len() is a function. The itertools chain function accepts *any* iterable. For this proposal to make sense, we can do no less. It isn't acceptable to: - only support a subset of iterables (unless there's an easy work-around); - expect everyone to add a chain() method to their iterable classes; - change the iterator protocol to require extra methods; - conflict with the + operator that already works with sequences; - choose an arbitrary operator that doesn't have at least some association with concatenation or chaining or addition (e.g. "?" would be unacceptible). Ideally, we should also be able to avoid conflicting with other operators as well, but given that there's only a small set of ASCII symbols to choose from, we should at least consider using an existing operator so long as: - we don't break existing code by changing the existing behaviour; - any clashes between the new and old behaviour should be uncommon (which is why + is unacceptible: using + on lists, tuples and strings is too common); - in any clash, the existing behaviour has priority over new behaviour (to avoid breaking existing code); - and there's an easy work-around to get the new behaviour (say, call iter() on the object first). -- Steve

On 2017-06-28 09:16, Steven D'Aprano wrote:
On Tue, Jun 27, 2017 at 01:53:37PM -0700, Mike Miller wrote:
On 2017-06-25 20:23, Steven D'Aprano wrote:
I have a counter-proposal: introduce the iterator chaining operator "&":
iterable & iterable --> itertools.chain(iterable, iterable)
I like this suggestion. Here's another color that might be less controversial:
iterable3 = iterable1.chain(iterable2)
That requires every iterable class to add its own reimplementation of chain, or else it will surprisingly not be chainable -- or at least it *sometimes* won't be chainable.
chain(iterable1, iterable2) would be more acceptable. The reason why a function would be better here than a method is explained in the FAQ for why len() is a function.
I still think a good middle ground would be to have such a function, but have the return type of that function be an iterator that provides a .chain method or (better) defines __add__ to allow adding it to other iterables. Then a single call to "chain" (or whatever the global function was called) would be enough to give you a nice readable syntax if you later want to chain other iterables on. This behavior would not need to be stipulated for any other kinds of iterators; "chain" would just be a function that converts any iterable into a nicely chainable one, similar to how pathlib.Path converts a string into a nicely manipulable Path object that allows various handy path operations. -- Brendan Barnwell "Do not follow where the path may lead. Go, instead, where there is no path, and leave a trail." --author unknown
participants (2)
-
Brendan Barnwell
-
Steven D'Aprano