On Thu, Apr 14, 2016 at 12:28 PM, Joseph Martinot-Lagarde <contrebasse@gmail.com> wrote:
> Guido van Rossum <guido@...> writes:
>
>> My rationale for this rule is that ending a line in a binary operator
>> is a clear hint to the reader that the line isn't finished. (If you
>> think about it, a comma is a kind of binary operator, and you wouldn't
>> move the comma to the start of the continuation line, would you?
>
> I personally tend to look more at the start of the lines because that's
> where the blocks are defined (by indentation). Also the end of the lines are
> usually not aligned which makes binary operators harder to see.
> Because of these two reasons I always put binary operator at the start of
> new lines, because that's where I have the most chance to see them, and I'm
> in favor of changing this in PEP8.

This is the case that jumped to mind for me as well...

If I saw code like this in a code review I'd force the author to change it because the style is outright misleading:

return (something1() +
        a * b +
        some_other_thing() ** 2 -
        f -
        normalizer)

We're summing a list of items with some things being negated, but that structure is impossible to see, and worst of all, the association between the operator and the thing being operated on is totally lost. OTOH if we write like this:

return (something1()
        + a * b
        + some_other_thing() ** 2
        - f
        - normalizer)

then the list structure is immediately obvious, and it's immediately obvious which terms are being added and which are being subtracted.

Similarly, who can even tell if this code is correct:

return (something1() +
        a * b +
        some_other_thing() ** 2 -
        f /
        normalizer)

but if the same code is formatted this way then it's immediately obvious that the code is buggy:

return (something1()
        + a * b
        + some_other_thing() ** 2
        - f
        / normalizer)

It should be corrected to:

return ((something1()
         + a * b
         + some_other_thing() ** 2
         - f)
        / normalizer)

(I'm calling the final item "normalizer" because this pattern actually comes up fairly often in bayesian computations -- if you're working in log space then at the end of some computation you subtract off a magic normalizing factor, and if you're working in linear space then at the end you divide off a magic normalizing factor. You can also get a similar pattern for chains of * and /, though it's less common.)

In all of these cases, the hanging indent makes the fact that we have a continuation line obvious from across the room -- I don't need help knowing that there's a continuation, I need help figuring out what the the computation actually does :-).

I actually find a similar effect for and/or chains, where the beginning-of-line format makes things lined up and easier to scan -- e.g. comparing these two options:

return (something1() and
        f() and
        some_expression > 1 and
        (some_other_thing() == whatever or
         blahblah or
         asdf))

return (something1()
        and f()
        and some_expression > 1
        and (some_other_thing() == whatever
             or blahblah
             or asdf))

then I find the second option dramatically more readable. But maybe that's just me -- for and/or the argument is a bit less compelling, because you don't regularly have chains of different operators with the same precedence, like you do with +/-.

I guess this might have to do with a more underlying stylistic difference: as soon as I have an expression that stretches across multiple lines, I try to break it into pieces where each line is a meaningful unit, even if this doesn't produce the minimum number of lines. For example I generally avoid writing stuff like:

return (something1() and f() some_expression > 1 and
        (some_other_thing() == whatever or blahblah or asdf))

return (something1() + a * b + some_other_thing() ** 2 -
        f - normalizer)

-n

BIKESHEDDING REDUCTION ACT NOTICE: I hereby swear that I have said everything useful I have to say about this topic and that this will be my only contribution to this thread unless someone addresses me directly.

--
Nathaniel J. Smith -- https://vorpus.org