One language feature conspicuous by absence in newbie confusions was, consistently, assignment expressions. Read any book or tutorial for such a language, and you'll find very little space devoted to them too.
[Łukasz Langa firstname.lastname@example.org]
Well, you have an entire code style built around this feature called Yoda conditions. You teach people on Day 1 to never ever confuse == with =. Some compilers even warn about this because so many people did it wrong.
Sorry, I couldn't follow that. In languages like C that use easily confused operator symbols, sure, people are forever typing "=" when they mean "==". That's nothing to do with whether they _understand_ what the different operators do, though. They do. In languages like Icon (that use "=" for numeric comparison and ":=" for assignment), that never occurs. But I'm not sure that addressed the point you were making.
What's to learn? If they understand "binding a name" _at all_ (which they must to even begin to write a non-trivial program), the only twist is that a binding expression returns the value being bound.
Ha, not in Python! Here we have different syntax for assignments in expressions.
Yes, binding expressions in the current PEP support an extremely limited subset of what Python's assignment statements support. That they use different operator symbols is irrelevant to that the meaning of "binding a name" is exactly the same for both.. _That's_ the "hard part" to learn.
Well, you can also use it as a statement. But don't!
Why not? _Every_ expression in Python can be used as a statement. Nothing forbids it, and that's even (very!) useful at an interactive prompt.
We have a better one for that.
As a matter of style, sure, it's best to use the simplest thing that works. As a statement in a program (as opposed to typed at a shell), "a := 3" has the unnecessary (in that context) property of returning (and discarding 3), so it's better style to use "a = 3" in that context.
And that one supports type annotations, can unpack and assign to many targets at the same time, and can even increment, multiply and so on, at once. But the other one can't.
So? math.sqrt() blows up when passed -1, but cmath.sqrt() doesn't. Different tools for different tasks.
So only use the Pascal one in expressions. But don't forget parentheses, otherwise it will bind the thing you probably didn't want anyway.
To my eyes, the examples give ample opportunity for being misunderstood and will create a need to puzzle-out the intended semantics.
Some do, many don't.
As soon as we have to wrap a part of an expression in parentheses, parsing the entire thing becomes more complex. Often enough it will cause the expression to exceed whatever line length limit the codebase pledged not to exceed, causing one line to become three. And again, making it trickier for a regular Łukasz to understand what's going on.
At this point I think you must have a lower opinion of Python programmers than I have ;-) If adding even a dozen characters to a line makes it exceed a reasonable line-length guide, the code was almost certainly too confusingly dense to begin with. All the binding-expression examples I've given as "improvements" had _oceans_ of horizontal white space to swim in.
Guido's if/elif/elif/elif/ ... complex text-processing example didn't,
but because the current lack of an ability to bind-and-test in one
gulp forced the
elif parts to be ever-more-deeply-indented
So, to match your sarcasm, here's mine: try using a feature for what it's good at instead of for what it's bad at ;-)