To argue that == is unreliable, I think Matthias has the best, non-contrived example with numpy, which I did not know about:
>>> x = np.array([1, 2, 3]) >>> x == None array([False, False, False]) This certainly is a good example of == not being reliable. Point taken there. Are there other such classes? Like if I write code that just uses Python and its standard library classes, can I get a value where == None is flaky like the numpy example? I wouldn't think so, just as a matter of principle-of-least-surprise API design. Anyway, that would be very interesting example to argue against my claim that == None is reliable. Best, Nick On Mon, Aug 30, 2021 at 12:06 PM Matthias Bussonnier < bussonniermatth...@gmail.com> wrote: > From my point of view as someone who sometimes help Scientist write > Python, this is a no go, there are too many cases where == and is are > different. > > $ ipython > Python 3.8.5 | packaged by conda-forge | (default, Sep 16 2020, 17:43:11) > Type 'copyright', 'credits' or 'license' for more information > IPython 7.25.0 -- An enhanced Interactive Python. Type '?' for help. > > In [1]: import numpy as np > > In [2]: a = np.array([True, False, None]) > > In [3]: a == True, a == False, a == None > Out[3]: > (array([ True, False, False]), > array([False, True, False]), > array([False, False, True])) > > In [4]: a is True, a is False, a is None > Out[4]: (False, False, False) > > if `a == True` can even raise errors when in ifs: > > In [5]: if a == True: > ...: pass > ...: > --------------------------------------------------------------------------- > ValueError Traceback (most recent call last) > <ipython-input-5-59a850ef5f8d> in <module> > ----> 1 if a == True: > 2 pass > 3 > > ValueError: The truth value of an array with more than one element is > ambiguous. Use a.any() or a.all() > > Basic types are just too simple to expose the real need between `==` > and `is`, but that's not a reason not to give the right advice from > the start. > IMHO It would be like teaching English and saying that it's ok not to > put s after nouns when there is a number in front as it's obvious > there are many. > > I do understand your concern, but I believe that would be just pushing > the problem to later, when it would be much more difficult to explain > and have students get a wrong mental model from the start, which is > really hard to overcome. > > -- > Matthias > > On Mon, 30 Aug 2021 at 11:45, Nick Parlante <n...@cs.stanford.edu> wrote: > > > > Hi there python-ideas - I've been teaching Python as a first > > programming language for a few years, and from that experience I want > > to propose a change to PEP8. I'm sure the default position for PEP8 is > > to avoid changing it. However, for this one rule I think a good case > > can be made to make it optional, so let me know what you think. > > > > Let me start with what I've learned from teaching students in Java and > > now in Python. In Java, you use == for ints, but you need to use > > equals() for strings. Of course students screw this up constantly, > > using == in a context that calls for equals() and their code does not > > work right. Then for Java arrays a different comparison function is > > required, and so it goes. To teach comparisons in Python, I simply say > > "just use ==" - it works for ints, for strings, even for lists. > > Students are blown away by how nice and simple this is. This is how > > things should work. Python really gets this right. > > > > So what is the problem? > > > > The problem for Python is what I will call the "mandatory-is" rule in > > PEP8, which reads: > > > > Comparisons to singletons like None should always be done with is or > > is not, never the equality operators. > > > > For the students, this comes up in the first week of the course with > > lines like "if x == None:" which work perfectly with == but should use > > is/is-not for PEP8 conformance. > > > > My guess is that this rule is in PEP8 because, within a Python > > implementation, it is within the programmer's mental model that, say, > > False is a singleton. The mandatory-is rule is in PEP8 to reinforce > > that mental model by requiring the is operator. Plus it probably runs > > a tiny bit faster. > > > > However, for "regular" Python code, not implementing Python, forcing > > the use of is instead of the simpler == is unneeded and unhelpful (and > > analogously forcing "is not" when != works correctly). What is the > > benefit of forcing the is operator there? I would say it spreads an > > awareness of the details of how certain values are allocated within > > Python. That's not much of a benefit, and it's kind of circular. Like > > if programmers were permitted to use ==, they wouldn't need to know > > the details of how Python allocates those values. Being shielded from > > implementation details is a Python strength - think of the Java vs. > > Python story above. Is Java better because it builds an awareness in > > the programmer of the different comparison functions for different > > types? Of course not! Python is better in that case because it lets > > the programmer simply use == and not think about those details. > > Understanding the singleton strategy is important in some corners of > > coding, but forcing the is operator on all Python code is way out of > > proportion to the benefit. > > > > As a practical matter, the way this comes up for my students is that > > IDEs by default will put warning marks around PEP8 violations in their > > code. Mostly this IDE-coaching is very helpful for students learning > > Python. For example, It's great that beginning Python programmers > > learn to put one space around operators right from the first day. > > Having taught thousands of introductory Python students, the one PEP8 > > rule that causes problems is this mandatory-is rule. > > > > As a teacher, this is especially jarring since the "just use ==" rule > > is so effortless to use correctly. In contrast, the mandatory-is rule > > adds a little pause where the programmer should think about which > > comparison operator is the correct one to use. It's not hard, but it > > feels unnecessary. > > > > As a contrasting example, in the language C, programmers need to > > understand == vs. is right from the first day. You can't get anything > > done in C without understanding that distinction. However that is just > > not true for regular (not-Python-implementation) Python code, where == > > works correctly for the great majority of cases. > > > > Here is my proposal: > > > > Add the following parenthetical to the mandatory-is rule: (this rule > > is optional for code that is not part of an implementation of Python). > > > > So in effect, programmers outside of a Python implementation can > > choose to use == or is for the "if x == None:" case. In this way, PEP8 > > conforming code before the change is still conforming. Moving forward, > > I would expect that regular code will trend towards using == in such a > > case, reserving is for the rare cases where it is needed for > > correctness. > > > > PEP8 was originally just for Python implementations, so why is this > > change needed? Because as a practical matter, the vast majority of > > code that is using PEP8 is not part of a Python implementation. This > > may not have been the original mission of PEP8, but it is how things > > have worked out. > > > > Now we are in a situation where the rules in PEP8 are sent out to this > > ocean of Python programmers of many different ability levels writing > > regular code that is not a Python implementation. One could imagine a > > separate PEP800 style guide for regular code, but we don't need to do > > that, because in almost all cases PEP8 works great for regular code. I > > have taught thousands of new Python programmers, and the only place > > where PEP8 serves them poorly is this mandatory-is rule. Therefore > > instead of a separate style guide for regular code, I propose an > > exception for this one problem rule. > > > > Ultimately this comes down to the question - should PEP8 push regular, > > not-Python-implementation code to use is for singletons in cases where > > == works perfectly? Seeing how effortless it is for programmers to use > > == as their first choice, I think PEP8 should allow that practice. > > > > Best, > > > > Nick > > _______________________________________________ > > 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/JWLKBT2YYDGFS76Z37FZJNZPEDVXOLCW/ > > Code of Conduct: http://python.org/psf/codeofconduct/ >
_______________________________________________ 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/ESQ6DEAJ3BT6BEA2TXYDGRLCRKBI5S53/ Code of Conduct: http://python.org/psf/codeofconduct/