On 2018-05-11 09:17, Steven D'Aprano wrote:
Much earlier in the PEP 572 discussion, I strongly argued in favour
of the

     expr as name

syntax on the basis that the most important part of the overall
expression is "expr", not the assignment target, and therefore that
should come first. Even though I have accepted that "as" is not viable,
I still believe that it is preferable to have the expression first, or
if not first, at least as close to the left as we can get it.

This "given" syntax puts the expr part all the way to the far right of
the line. A line which is made all the longer for needing to use "given"
and redundantly state the target name.

It's like we're trying to maximize the distance the eye has to travel
back and forth when reading.

I have to read to the end of the line before I have any idea where cmd
has come from or what it is. The fact that it comes from a "given"
expression comes as a surprise at the end of the line.

Now obviously this doesn't matter if I'm reading lines of code in
careful detail, but I don't do that all the time. I skim code far more
than I read it in careful detail, and the closer things are to the left,
the more likely I am to see them while skimming. The further out they
are, the easier they are to miss.

I think that "given" will*literally*  make reading harder, in that the
eye has to travel further to spot the relevant expression while skimming
over code. As I said, I don't think it makes any difference when reading
closely in detail. But most of my reading of code is skimming to find
the relevant line or section, and then read closely. I would probably
skim a hundred lines for every one I read closely.

That is an interesting argument --- interesting to me because I agree with a lot of it, but it leads me to the opposite conclusion, and also because it highlights some of the relevant factors for me.

The main part I disagree with is that the most important thing is the definition of expr. Rather, what I think is most important is the role of expr within the surrounding expression. For simple cases, it doesn't much matter which comes first:

        if x := do_some_stuff():

        if x where x = do_some_stuff():

. . . and it's true the latter is a bit more verbose in that case for little extra benefit. But when the locally-defined value is used within a more complicated expression (like the quadratic formula example), I think readability goes down significantly. To appease Tim, instead of using the quadratic formula, though, I will use a more realistic example that comes up fairly often for me: wanting to do some kind of normalization on a piece of data for a comparison, while keeping the unnormalized data for use within the block:

if some_condition and (stuff:= get_user_input()).lower().strip().replace('-', ''):

versus

if some_condition and stuff.lower().strip().replace('-', '') given stuff = get_user_input():

Now, the latter is still more verbose. But to me it is now more readable, because the assignment does not disrupt the flow of reading the surrounding expression. This benefit increases the more complicated the surrounding expression is.

Your point about reading ease is well taken, but also relevant to me is that we only read a piece of code *for the first time* once. The advantage of the given-style assignment is that on multiple readings, it foregrounds how the assigned value is USED, not how it is DEFINED. This encourages a "top-down" understanding of the expression in which you first understand the overall picture, and then later "drill down" into definition of what the components are.

I wonder if some of the disagreement about the relative merits of the two cases comes from people focusing on different kinds of examples. As I said, I think the advantages of "cleft assignment" (i.e., where the assignment is shunted to the end of the line) become more pronounced as the surrounding expression becomes more complex. They also become somewhat greater as the definition of the expression becomes more complex, because there is more to skip over when finding out how the value is used. But many of the examples we're seeing are very simple ones, and in particular have a trivial surrounding expression. (That is, in something like "m := re.match()" the assigned value is not being used in any larger expression; the assigned value constitutes the whole of the expression.)

I'm also finding it useful to think of parallel situations in prose writing, particularly journalistic-style prose writing. The current Python behavior, in which assignments must be done before the block, I think of as akin to something like this:

"The IAAEA (International Association of Assignment Expression Advocates) is an organization dedicated to the promotion of assignment expressions. Its president is Eddie McEquals. In a statement yesterday, McEquals called for a new syntax to bring assignment expressions to the masses."

        The inline-assignment syntax is akin to this:

In a statement yesterday, Eddie McEquals, president of the International Association of Assignment Expression Advocates (IAAEA), an organization dedicated to the promotion of assignment expressions, called for a new syntax to bring assignment expressions to the masses.

        The cleft-assignment syntax is akin to this:

In a statement yesterday, Eddie McEquals called for a new syntax to bring assignment expressions to the masses. McEquals is the president of the International Association of Assignment Expression Advocates (IAAEA), which is an organization dedicated to the promotion of assignment expressions.

Now of course I'm fudging a bit on the details (like whether you have IAAEA in parentheses or its full expansion), but the point is that the last version foregrounds the "bottom line" or "predicate" --- what actually happened. The first one foregrounds the "participants", or who/what was involved, and saves what actually happened for the end. But the middle one, to my eye, foregrounds nothing. It stuffs everything into one big clause where the descriptions of the participants occur as asides that disrupt the flow of reading. By the time we get to the predicate, we have to jump back to the beginning to remember who it is we're talking about,

Again, the difference in readability varies depending on the complexity of the different components. If we just have "Eddie McEquals, president of the International Association of Assignment Expression advocates, delivered a speech yesterday at the organization's convention", the inline appositive is not so disruptive. But the more complex the inline definitions become, and especially the more complex the expression in which they are embedded, the lower readability goes, for me.

--
Brendan Barnwell
"Do not follow where the path may lead. Go, instead, where there is no path, and leave a trail."
   --author unknown
_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to