[Python-ideas] PEP 572: Statement-Local Name Bindings, take three!

Tim Peters tim.peters at gmail.com
Sun Mar 25 23:34:19 EDT 2018


[Tim]
>> I wonder whether Guido remembers this ;-)  In the very, very, VERY
>> early days, Python didn't have "==".  Plain single "=" was used for
>> both assignment and equality testing.

[Guido]
> Wow, I did not remember this. In fact I had to track down the 0.9.1 release
> that's somewhere on the web to see for myself. :-) Should add this to the
> HOPL-IV paper if I end up writing it (I'm still far from decided either
> way).

See?  I'm still good for _something_ sometimes ;-)


>> I'm not clear on why it changed.  I remember writing to Guido about
>> how to disambiguate between the "bind" and "test for equality" intents
>> in isolated expressions typed at the interactive prompt, and next
>> thing I knew the language changed to use "==" for the latter.

> Hm, that's probably why -- the desire for top-level expressions to allow
> comparison. Also probably the realization that this is one thing where (at
> the time) this particular difference with C/C++ was just annoying for most
> new users.

I don't have my email from those days, and have futilely tried to
recall details.  IIRC, it had never been discussed on the mailing list
before, or in any private emails before.  It just popped up one day
when I was working in a Python shell, and there was _something_ subtle
about it.  You wrote back and expressed disappointment - that you had
really wanted to keep "=" for both purposes.

I started writing a reply suggesting a way out of whatever-the-heck
the problem was, but before I finished the reply the next day you had
already changed the implementation!  Things moved quickly back then
:-)

Anyway, if your time machine is in good working order, I'd be pleased
if you went back and restored the original vision.  If, e.g., we
needed to type

>>> (x = y)
True

at the shell to get a top-level equality comparison, BFD.  I can't
believe it was _that_ simple, though.


> I'm assuming that <>, the ancient alternate spelling for != (that Barry
> still misses), came from the same source: ABC
> (https://homepages.cwi.nl/~steven/abc/qr.html#TESTS). But there was no
> compelling reason to remove <> (only to add !=) so it lingered until 3.0.
> Presumably ABC got both from Pascal
> (https://www.tutorialspoint.com/pascal/pascal_relational_operators.htm).

Good inspirations!  As noted next, at least Pascal used ":=" for assignment too.


> ...
> Most languages I learned in the '70s used it: both Algols, Pascal. (Though
> not Fortran.)

I mentioned Icon because I'm sure Pascal didn't have "embedded
assignments" at all.  Unsure about Algol, but I'd be surprised
(certainly not Fortran).

Icon has no "statements" at all:  _everything_ in Icon is an
expression, generating zero or more values.  Embedded assignments are
frequently used in idiomatic Icon, so I think it's especially relevant
that I recall no bugs due to Icon's use of ":=" (for assignment) and
"==" (for equality).  Programmers simply never used one when the other
was intended.  In C, essentially everyone uses "=" when they intend
"==" at times, and - as noted - I _still_ do that in Python regularly
to this day.  I'd be screwed if I got an unintended assignment instead
of a SyntaxError.


> ...
> The "two pages back" problem can happen just as easy with regular
> assignments or for-loop control variables.

Yup, but eyeballs don't have to scan every square inch of the screen
for those:  `for` statement targets are easy to find, and assignment
statement targets start flush with the first non-blank character of an
assignment statement, where the eye naturally leaps to.  When
assignments can be embedded anywhere, you have to look everywhere to
find them.

But so it goes.  Even if that can't be _stopped_, it's a matter of
good practice to avoid making code inscrutable.

> ...
> I gotta say I'm warming up to := in preference over 'as', *if* we're going
> to do this at all (not a foregone conclusion at all).

I'm not assuming it will go in, I just want to nudge the PEP toward a
proposal that doesn't suck so bad it's obviously doomed ;-)  I'm
uncertain whether I'd support it anyway.  I do know that, e.g.,

    if m := match(string) is not None:
        # do something with m

violates my sense of outrage less than anything else I've seen ;-)
And, ya, I'd _use_ it if it were implemented.  But I can (continue
to!) live without it.


> The scope question is far from easy though. I find it particularly grating
> that an inline assignment occurs in an 'if' statement, its scope is the
> entire body of the 'if'. If that body is two pages long, by the end of it
> the reader (or even the writer!) may well have lost track of where it was
> defined and may be confused by the consequence past the end of the body.

See my "every square inch" above ;-)  At least if the scope _is_
limited to the body of the `if`, it's far more limited than in C or
Icon.  Of course I'm more interested in whether it can be used to
write clearer code than in whether it can be abused to write muddier
code.

List comprehensions leapt to mind there.  They're wonderfully clear in
prudent doses, but for a while half my Stackoverflow answers started
by chiding the questioner for an irrational fear of writing obvious
loops instead ;-)


More information about the Python-ideas mailing list