back to index

The most controversial Python feature | Walrus operator


Chapters

0:0 Walrus operator
1:26 Use cases
3:33 Criticisms
5:59 Guido van Rossum

Whisper Transcript | Transcript Only Page

00:00:00.000 | This is the walrus operator, and this is the assignment expression that it enables.
00:00:05.600 | It's been added as a feature to Python 3.8 after a whole lot of drama. Majority of Python core
00:00:12.720 | developers, as far as I can tell, were against it, and the drama and toxicity over it drove Guido van
00:00:19.120 | Rossum, creator of Python, to step down from his leadership role of benevolent dictator for life
00:00:25.200 | after he accepted the walrus operator as part of the PEP 572 proposal. So what is it? First,
00:00:32.320 | let's talk about the assignment statement, the equal sign in Python. We can thank Fortran for
00:00:39.760 | this, I think, not very good design decision of using the equal sign for assignment. So assigning,
00:00:47.440 | in this case, 42 to the variable x. Most programming languages use it, with a few exceptions.
00:00:53.360 | Pascal uses the walrus operator for assignment, and R uses a different operator. This goes against
00:01:01.200 | the notation of mathematics, where the equal sign is used to designate equality. But there's a
00:01:07.040 | lesson here, I think, that even bad design decisions, once accepted and once we get used to them,
00:01:11.680 | aren't so bad. It's all about consistency. So the assignment expression does a little bit more. It
00:01:17.920 | also signs 42 to x, performs the assignment operation, but as an expression, it returns
00:01:24.160 | the value that it assigned as well. This can be useful in a lot of contexts. Let me talk about the
00:01:29.280 | cases where I find them particularly useful. So I use regular expressions a lot as part of data
00:01:34.960 | science to clean up and organize data. So a common piece of code you might see is you perform a
00:01:40.080 | regular expression match, returning it to a variable like res here, that contains the regular
00:01:46.960 | expression object if a match was found, and contains none if no match was found. And then
00:01:52.160 | you have some kind of conditional, like an if statement, that checks whether a match was found.
00:01:56.560 | And if it has been found, then you do something with the regular expression object. In Python 3.8,
00:02:01.680 | all that gets combined into a single line that performs the match operation, assigns the result
00:02:08.880 | of the match to res, and then check if res contains a regular expression object. A similar use case
00:02:15.360 | is in reading files. There's a lot of ways to read a file, but a lower level version, there's
00:02:20.080 | usually a while loop. Then there's a read operation that's stored in the chunk variable or something
00:02:24.880 | like that. And then there's a condition that checks whether the chunk contains anything,
00:02:28.320 | or if an end of file was reached, at which point you break out of the while loop. If it has not
00:02:32.960 | been reached, then you do something with the data that was fetched. In Python 3.8, this gets
00:02:38.160 | compressed into a single line that performs the read operation, the assignment of the fetched data
00:02:43.600 | to the variable chunk, and then the conditional check in the while loop of whether chunk returned
00:02:48.800 | any data or if the end of the file was reached. To me, this is elegant. Other use cases in list
00:02:54.560 | comprehensions, you can share sub-expressions. Like in the filter, you can assign f of x to y,
00:03:00.720 | and then reuse that y in the output of the comprehension. You can also, in a list,
00:03:06.000 | reuse a value. For example, if it's expensive to compute, so you can compute f of x once,
00:03:11.280 | assign it to y, and then reuse y in the rest of the list definition. As a side note, I don't like
00:03:16.640 | to use chained assignments, but chain assignments have the same feature that the function f is only
00:03:22.640 | computed once. So this particular statement here is equivalent to computing f once, assigning it
00:03:28.320 | to a temp variable, and then assigning that temp variable to both x and y. There are quite a few
00:03:34.160 | criticisms that are both objective and subjective that talk about the complexities of programming
00:03:40.560 | language design and human nature in general. So first is the idea that both the equal sign and
00:03:46.800 | the walrus operator perform an assignment, so it might be confusing to beginners. I'm not sure about
00:03:52.320 | the history of PEP 572, but my guess is that this criticism was more prevalent before the exception
00:03:58.800 | was added. That assignment expressions can't be on a line standalone by themselves without using
00:04:04.160 | parentheses. I think this clarifies to beginners that assignment expressions should not be used
00:04:09.280 | as an assignment statement. There's a set of principles defined in PEP 20, otherwise called
00:04:14.560 | "Design of Python" that has some ideas to aspire to in the design of Python. Just like Guido said,
00:04:20.800 | some of these are subjective, and I think they are ideas to aspire to as opposed to perfectly
00:04:26.720 | implement because they're overlapping and there's a natural tension between them. So the first
00:04:31.600 | principle that's been brought up is there should be only one obvious way to do it, and some people
00:04:36.560 | argued that the walrus operator performs an operation that already had another way to do
00:04:42.320 | the same exact thing. I've also heard a funny kind of criticism that the equals operator
00:04:46.960 | worked like an assignment expression in C, and it kind of sucked in C, or at least was error-prone.
00:04:53.520 | So there you go, you have a case study in the real world where this kind of operator being used to
00:04:58.240 | designate an assignment expression was error-prone. Another "Design of Python" principle that people
00:05:03.680 | brought up is that simple is better than complex, and while it seems that the assignment expression
00:05:10.160 | makes the code simpler, in fact, it was argued that it was only reducing white space and was
00:05:15.760 | in fact adding complexity, or at least moving the complexity. Finally, the criticism that applies
00:05:22.080 | often in programming language design is that not enough testing was done on how actual developers
00:05:27.520 | will use it. I think that's probably the biggest challenge of programming language design, and
00:05:32.240 | design in general, is you don't know how people, how thousands or millions of developers are going
00:05:37.200 | to use this feature once it's in the wild, and how other features will interact with it when it's in
00:05:42.960 | the wild. So this criticism is certainly true, but I think it is always true. My own feelings about
00:05:49.440 | the walrus operators, I think when used properly, it's quite elegant and even beautiful, but it also
00:05:57.440 | represents more than that. To me, it represents the importance of leadership in a community of
00:06:02.320 | smart people that disagree. So this is the feature that led Guido to resign, and I spoke with him on
00:06:08.240 | the podcast that I host, and I'll speak to him again. I think he's one of the most brilliant
00:06:13.600 | language designers and programmers we have, also a great leader in the software engineering community.
00:06:18.720 | So this is a little excerpt from a post he made. It reads, "Now that PEP 572 is done,
00:06:25.200 | I don't ever want to have to fight so hard for a PEP and find that so many people despise my
00:06:30.320 | decisions. I would like to remove myself entirely from the decision process. I'm basically giving
00:06:36.080 | myself a permanent vacation from being BDFL, and you all will be on your own. So what are you all
00:06:43.760 | going to do? Create a democracy? Anarchy? A dictatorship? A federation?" So to me, the walrus
00:06:52.240 | operator represents more than just assignment expressions. It represents the power of
00:06:56.720 | leadership to break through a toxic stalemate. I think leaders have to make difficult decisions,
00:07:04.640 | sometimes unpopular decisions, and sometimes ones, if you look at the long arc of history,
00:07:12.320 | prove out to be bad decisions. But without leadership, I think we can't make progress. So
00:07:19.680 | the messiness, the chaos of democracy, is that the divisiveness can be paralyzing.
00:07:26.240 | And we need leaders to inspire us, to guide us, and to make difficult, risky decisions.
00:07:34.560 | So to me, the walrus operator would be useful for regular expressions, but it will also be a
00:07:40.480 | reminder of the importance of leadership in the programming world and in our world in general.
00:07:47.280 | If you enjoy these short little videos, subscribe, and remember, try to learn something new every day.
00:07:58.140 | [BLANK_AUDIO]
00:08:05.760 | [BLANK_AUDIO]