On Sat, May 16, 2020 at 1:26 AM Steven D'Aprano <st...@pearwood.info> wrote:

>
> > * zip(strict=True)       +1
> > * zip(mode='strict')     -0
> > * itertools.zip_strict() -0.5
> > * zip.strict()           -1  (but really, I'd like to make this -1e10)
>
> I spent a significant amount of time and mental energy explaining in
> detail why a boolean flag is a poor API and is objectively the wrong
> interface here. This is not just a matter of personal taste: there are
> reasons why a flag is wrong here.
>

Clearly it is not the objective truth, otherwise you would have an easier
way convincing everyone. :-)


> Flags are for combining independent and orthogonal settings which can be
> combined. This is not such a feature. I think it is objectively the
> worst API on the table here, for reasons already discussed.
>

Sorry, Ihave to object to your use of the word "objectively". Clearly
what's worst depends upon one's perspective.


> - Your preferred option makes the strict zip version a second-class
>   citizen of the language;
>

With any other option it will still be that -- "zip" is the dominant name
here, (a) because it's so short, (b) because it's somehow a memorable word,
(c) because it's been around for 20 years.


> - your preferred option is the least open to future enhancements;
>

Given zip's stability, I doubt there will be a lot of other future
enhancements any time soon. In Python's culture, boolean flag is the most
common way to modify the behavior of a function. The reasons have to do
with tradition (lots of existing APIs use this pattern) as well as ease of
implementation (*also* in the Zen!), and also with how people *think* about
certain APIs. Zip-strict is "like zip, but strict(er) in its requirements".


> - your most hated option is the one which follows the Zen of Python
>   the most closely (namely, the koan about having more namespaces);
>

I'm sorry, I'm not buying this. While for *classes* , alternate
constructors are a well-known pattern (dict.from_keys(),
datetime.fromtimestamp(), etc.), for *functions* (and almost everyone
thinks of zip as a function -- including the docs
<https://docs.python.org/3/library/functions.html#zip>!) this pattern is
uncommon, and awkward to implement. (You have to write it as a separate
function and then make that function a function attribute of the first
function.)

It is also quite uncommonly found -- no other builtin *function* uses it,
and only one function in itertools uses it. I know there are 3rd party
frameworks that use this convention, and as a general convention for a
framework it's fine. But for an existing builtin function I think a lot of
people will do a double-take when they read it in someone else's code
(thinking it may be a typo). Whereas nobody will lift an eyebrow when they
see zip(a, b, strict=True) -- even if they've never heard of it, they
immediately know that it's a modification to the zip() behavior they know.


> - and is the most object-oriented solution (it's effectively a method);
>

That's not even an argument. (It's abuse
<https://www.youtube.com/watch?v=ohDB5gbtaEQ>. :-)


> - and most importantly you explicitly *oppose* every alternative API,
>   giving them negative preferences; you would rather not have this zip
>   variant at all than have an interface other than a boolean flag.
>

I think that's a fallacy. Opposing a proposal is not the same as saying you
would rather have nothing than that. It simply expresses a strong negative
reaction.

If I needed this function[1], I'd accept it even if it were spelled
> `xyghasx.peyahc.flihaj()` and required me to set a global variable to
> make it work. So I can't help but interpret your total opposition to
> every other interface as a strong sign that you don't really need this
> zip variant at all. If your opinion is typical, perhaps we should just
> reject the PEP.
>

Another straw-man. My personal vote, for example, is +1 on zip(strict=True)
and -1 on zip.strict(). But if the SC chooses the latter, I'll happily use
it.


> Could you explain why you believe a bool flag is the only
> suitable interface? Objective reasons preferred please.
>

An unreasonable request. I've tried to explain above why in the context of
where we are (Python 3.9) I find it the best option.


> The same goes for everyone else who gave a vote. If you have an
> objective reason for wanting this strict zip function to be a second
> class citizen that cannot be easily extended in the future, then please
> explain why.
>

It will *always* be a second class citizen, no matter how you name it,
unless you change the behavior of zip(), which is off the table.


> [1] I don't think I do. If I had my preference, thinking only of my own
> needs, I'd probably reject the PEP. But I acknowledge that others seem
> to need it.
>

Then I really have to wonder why you are so invested in convincing everyone
that your proposal is the only one that's objectively acceptable.

Finally, I have to clarify something. In the past I've often said that if
you're thinking to introduce a boolean flag to an API that's always going
to be passed as a constant (if at all), you're probably better off with a
separate function. This would seem to be such a case. Yet I am not
following my advice. Why? (a) It's a rule of thumb, and in this case I find
zip_strict() just a bit less clean than zip(strict=True); an relegating it
to itertools.zip_strict() makes it a lot less attractive. And (b) That rule
is most important when the flag affects the *return type* of a function.
This is because static checkers have a hard time with such APIs.
(Almost-example: open(..., "rb") returns an IO[bytes] while open(..., "r")
returns an IO[str].)

PS. Why wasn't a new builtin zip_strict() on the menu? I think I would have
given it at least +0.5, because of this rule of thumb.

-- 
--Guido van Rossum (python.org/~guido)
*Pronouns: he/him **(why is my pronoun here?)*
<http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/LZGAKYCX2HTQCEM3WBH2Y5CMEI6XRRVN/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to