On Wed, May 6, 2020 at 6:49 PM Christopher Barker <pythonchb@gmail.com> wrote:
On Tue, May 5, 2020 at 5:43 PM Steven D'Aprano <steve@pearwood.info> wrote:
Christopher's quoting is kinda messed up and I can't be bothered fixing
it, sorry, so you'll just have to guess who said what :-)

Ideally, we are evaluating ideas independently of who expressed them, so I'll pretend I did that on purpose :-)

First: really people, it's all been said. I think we all (and I DO include myself in that) have fallen into the trap that "if folks don't agree with me, I must not have explained myself well enough" -- but in this case, we actually do disagree. And not really on the facts, just on the relative importance.

But since, I apparently did not explain myself well enough in this case:
> no -- but we could (and I think should) have a ternary flag, so that
> zip_longest becomes unnecessary. And we'd never get to eight combinations:
> you can't have longest and shortest behavior at the same time!

A ternary flag of strict = True, False or what?

...

a flag that takes three possible values: "shortest" | "longest" | "equal" (defaulting to shortest of course). Name to be bikeshed later :-)
(and enum vs string also to be bikeshed later)

This demonstrates why the "constant flag" is so often an antipattern. It
doesn't scale past two behaviours. Or you end up with a series of flags:

    zip(*iterators, strict=False, longest=False, fillvalue=None)

I don't think anyone proposed an API like that -- yes, that would be horrid.

There are all sorts of reasons why a ternary flag would not be good, but I do think it should be mentioned in the PEP, even if only as a rejected idea.

But I still like it, 'cause the "flag for two behaviors and another function for the third" seem sliek the worse of all options.


I'm totally agree with everything you said here. From my perspective, comparing three main cases:
1. zip(*iters, strict= (False | True))
2. zip(*iters, mode = ('shortest' | 'equal' | 'longest'))
3. zip_equal(*iters)

The first case looks like pretty bad idea (maybe it is practical). But every of the provided cases try to solve the same problem, so from practical point of view they are all the same. So just as you said the first case is merely "flag for two behaviors and another function for the third" -  is solid -1 from my side.

I like how the second case looks and feels, but obviously the proposed signature (solution) will not be enough. To plug in the existing functionality from zip_longest you will also need to provide fill= kwarg, like zip(*iters, mode = ('shortest' | 'equal' | 'longest'), fill=None). This fill kwarg will be ignored for other to cases  'shortest' and 'equal'. Heh - it is not perfect. I will give +0.1 for the second case.

The third case is rather usual solution for the real problem (just one more function in stdlib) - so +0.5 for this case from my side.

-gdg