seeking deeper (language theory) reason behind Python design choice
Ian Kelly
ian.g.kelly at gmail.com
Wed May 9 01:36:06 EDT 2018
On Tue, May 8, 2018 at 9:48 PM, Python <python at bladeshadow.org> wrote:
> On Tue, May 08, 2018 at 12:45:29AM +0000, Steven D'Aprano wrote:
>> since = in a statement on its own is not dangerous. People *almost never*
>> intend to write == for the side-effects only:
>
> Seriously? I do this--not every day, but more than occasionally, not
> just in Python.
>
> flag = (spam == arg)
> vs.
> if spam == arg:
> flag = True
> else:
> flag = False
> if flag:
> do_something()
> else:
> do_something_else()
As Chris pointed out, this is not an example of using == for side-effects only.
>> # don't care whether they are actually equal or not
>> # just want to call the __eq__ method for its side-effects
>> spam == arg + 1
>>
>> Since that never happens in real life, there's no risk of accidentally
>> writing "spam = arg + 1" when you wanted "spam == arg + 1".
>
> I've always felt that this mentality was insulting to the programmer:
> "You're too stupid to get this right." Sure, I've created that bug in
> other languages (or rather its inverse) but not since college. You
> make it a few times, you go nuts debugging it, you learn what it is,
> you never do it again.
>
> And, this kind of thing is what code reviews are for--Python isn't so
> idiot-proof that you can get away without doing them for any
> non-trivial code--so (IMO) the language should not prevent you from
> doing useful things *simply* because you *might* make a mistake.
I do code reviews every day, and I doubt that I would actually notice
if one of them slipped in '=' where '==' was intended. Hopefully it
would be caught by unit testing though.
> I'll
> give you an example that is both a case where Python's design choices
> make creating a bug easier, AND a case where allowing assignments to
> be expressions would save you.
>
> flag = we_are_done()
> while not flag:
> # do some stuff
> ...
> if error_occured():
> break
> falg = we_are_done()
> notify_user()
> # flag will be checked again later, perhaps for error reporting
while True:
if we_are_done():
break
# do some stuff
...
if error_occurred():
break
notify_user()
Fixed, using idiomatic Python and without needing to use assignment in
an expression.
> Here, a common programming pattern (prime the loop control variable)
> gets you in trouble, because the assignment happens in two places, and
> you mistyped one of them. There's no syntax error, but your program
> will execute forever, unless you were already done on the first call
> to prime the flag, or an error occurs. This is probably worse than
> the = vs. == error, because your brain tends to "autocorrect" certain
> kinds of spelling errors, whereas experienced programmers learn to
> look for (or avoid entirely) the assignment vs. comparison bug. The
> error here is reasonably easy to spot, given the trivial nature of the
> example, but would likely be harder to spot in more complex code with
> longer, more meaningful variable names.
>
> This example also is a case FOR allowing assignments to be
> expressions. If Python allowed them, you could rewrite this as:
>
> while not (flag = we_are_done()):
> ...
> if error_occured():
> break
> notify_user()
> # flag will be checked again later, perhaps for error reporting
>
> This COMPLETELY PREVENTS the spelling bug in the code above, since the
> assignment only happens in one place; and as a bonus it's less code.
Or just use an IDE with variable name autocompletion.
More information about the Python-list
mailing list