It's the most controversial feature ever introduced because it goes against a lot of python culture and philosophy.
All in all the debate has been heated and long, but it has been decided that the python community will use it intelligently and rarely, but that when it matters, it can help a lot.
I'm against this feature, while I was pro f-string. However, I'm not too worried about missuse and cultural shift because I've seen 15 years of this show going on and I'm confident on it's going to be indeed tagged as "risky, use it knowing the cost" by everybody by the time 3.8 gets mainstream.
My metric for this is to put some of my freshest student in front of a code and see how they deal with it. How easily can they understand it ? How easily can they write it ? Debug it ?
They are most of the time a fantastic indicator of the cognitive load a feature will add in prod. Because of course a feature doesn't exist in a vacuum, it's always in a more complex context. So what's easy to understand for a student will be alright for a pro in the complexity of real life engineering. And I found the opposite to hold quite often as well.
I haven't tried the walrus on them yet, but I'm pretty sure of the result.
> my freshest student in front of a code and see how they deal with it.
That is fine if you want to optimize language for "fresh students". That is not representative how brain process stuff after getting even some experience.
It's not about experience vs inexperience... it's about code readability and being unsurprising.
m = re.match(...)
if m:
... do something ...
is verbose, but quite readable. Given that it's the way things have been done since forever, it's also unsurprising.
if m := re.match(...):
... do something ...
Without knowing what the walrus operator is, it is not entirely clear what is going on here. := is only syntactic sugar, which is not what Python has ever been about.
If feel Go solves this in a much more readable way.
if m := re.match(...); m {
... do something ...
}
Still not as readable as splitting it over multiple lines but quite a lot better than Python's syntax IMO especially once you learn how the if statement works in Go.
I for one predict that the new operator will appear very sparingly, in while loops and code golf competitions.
There are already so many complicated semantics about mutability, iteration, bytes/strings, scoping, et al. And yet somehow a tiny piece of syntax that finally lets us stop writing "while true/break" is the big pain point?
I'd expect the new operator to become the idiomatic way to write certain quite common things, for example regexp group matching and objects returned by dictionary .get() - currently you always need a dummy variable to check if it's not None before you use it.
I write a good deal of python and I can't think of a line of code that I would use it for besides the while loop on a non-iterable data source, which is such a once in a blue moon case. As mentioned by others, the operator invites more ways to do the same thing, which is not what Python has been viewed as being about.
Victor Stinner made a demonstration pull request using the walrus operator in the standard library where it makes sense. On balance it removes several hundred lines and often makes the code much clearer, e.g. https://github.com/python/cpython/pull/8122/files#diff-78e8e...
The walrus simultaneously names the value being tested so you can refer to it within the condition; it's sort of the inverse of Perl code using $_. So instead of
if (do_something()) {
act_on($_);
}
you have
if placeholder := do_something():
act_on(placeholder)
But when reading aloud, however you'd read the perl will flow as more natural english. "If the string contains z, do something with it".
If you really want to read the Python as it's written, it corresponds to the second of these sentences:
- If the substring from 3 to 5 is "fg", crash.
- If variable_name, the substring from 3 to 5, is "fg", crash.
Once way to test if this works is to take the code, read it aloud, and then use the read-aloud version to rewrite the code. If you don't have a high degree of certainty that you end up with the same code, something has failed along the way.
In this case, if I take "if x:= y()" and read it aloud as "if y", I think the vast majority of people would translate that to code as "if y():", which isn't the same thing.
That second point is quite an assumption to make. If it's okay to end up with the second one of your examples (without the ":=" operator), why did we need to add the walrus opeprator at all?
And if you're referring to this statement from your original comment:
> If variable_name, the substring from 3 to 5, is "fg", crash.
I don't find this to be a clear statement at all. If I read this aloud to any of my programming students, I doubt any of them would be able to decipher it into any code, let alone the code string which you've suggested.
> If it's okay to end up with the second one of your examples (without the ":=" operator), why did we need to add the walrus operator at all?
A couple of reasons:
- The walrus eliminates a line of code in the very common scenario where you would prefer not to recalculate (or retype) y().
- The walrus makes it easy to avoid recalculating y() in the less common scenario where you need to avoid doing that.
> I don't find this to be a clear statement at all.
Nonetheless, it is the normal English syntax used to name something and then immediately define the meaning of that name. If you want to map the Python structure to an equivalent English structure, that is the equivalent English structure. ("Thomas Jefferson, the third president, was a man about whom much can be said.") If you want to map the Python code to an English statement of what the code does, use the reading I first suggested, "if y(), do something with it". If you want to dictate Python code to an English speaker, use the reading "if x colon-equals y()".
So let me ask you: is the problem you'd like to solve "I want to understand what this code does", is it "I like thinking about English grammar", or is it "I'm too busy to type my own code; that's what my secretary is for"?
You could read "if x := y()" as "if x gets a truthy value from y()."
For what it's worth, "x = y()" is one of the harder things for new programmers to translate to English in the first place -- it reads most naturally as "x equals y," but leads to better intuitions as "x gets the value of y". I think that's what makes this clunky to verbalize, rather than the "if truthy" bit.
It's not that common. There's 1 place where its useful imo (comprehensions to avoid duplicate calls), but even that can be handled case by case, and it certainly isn't a common thing.
Disagree. In my experience (albeit, not very long, been writing Python since 2007 or so), assigning to a value and checking for truthiness is a very common pattern.
Very common pattern, confusing nonetheless. It does two different things at once where traditionally Python is explicit and only does one thing at once.
I've had to use a workaround for that every time I've tested a regular expression match that I wanted to process for example. Also problematic in comprehensions...
Actually it doesn't violate any of the principles behind the language. It could have been there from day one, like tons of others things added later and now totally loved.
I should know, I've worked with Python for 22 years...
Quoth the PEP[1], Guido changed his mind when he found proof that coders would write redundant (and expensive) code to avoid using a separate line to construct a temporary variable.
So one might argue that a principle of python is that the language is dictated by how people read and write rather than the other way around... it's pretty hard to say what principles are "core" when they all conflict and you have to weigh various tradeoffs.
20 years after. It took 2 decades. My impression from the debate, and taking in consideration the political context, is that he saw that as the tipping point of the BDFL transition and a good test run as much as a language feature.
I'm not following what you're saying it's a test run of. I agree that he probably wanted to cease being BFDL because it's a big job, but with the caveat that I'm terrible at following Internet drama, he did seem genuinely surprised at the outrage.
Regarding that it took 25 years, the normal Python syntax has been enormously successful. People don't tend to look for problems in things that work.
>Guido disagrees and rejected the idea multiple time in the last 2 decades. I think he worked on Python for a long time too :)
Guido also rejected several ideas that would totally fit with Python in those decades. There are lots of concerns (including implementation ones), not just what fits with some hypothetical "Zen", which was never meant as a contract anyway.
Besides Guido finally agreed to it, and even quit because of it.
If Python was to be kept "simple" at all costs, it would have added 20 other things, from operator overloading to yield from over those decades, some far more complex, and non-local than the operator change.
That’s an impressively incorrect history of the operator.
The zen of Python is not a binding constitution. It does not mean nothing can be added if there is some way to do it already, especially if that way improves things. It’s no more “going against the principles” than f-strings where, and they turned out just great.
I worked with Python for many years as well. I recently switched to another language...
You can browbeat people all you like but we are not forced to work with any particular language and if it diverges away from what we liked we will just switch away.
All in all the debate has been heated and long, but it has been decided that the python community will use it intelligently and rarely, but that when it matters, it can help a lot.
I'm against this feature, while I was pro f-string. However, I'm not too worried about missuse and cultural shift because I've seen 15 years of this show going on and I'm confident on it's going to be indeed tagged as "risky, use it knowing the cost" by everybody by the time 3.8 gets mainstream.