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.
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)
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/%7Esteven/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 ;-)