[Python-ideas] On evaluating features

Stephen J. Turnbull turnbull.stephen.fw at u.tsukuba.ac.jp
Fri Aug 31 03:25:07 EDT 2018


Executive summary: Although I'm obviously not particularly in favor of
this feature, my opinion is no more valuable than anyone else's.  The
point of this post is to show how features have been advocated
successfully in the past.

James Lu writes:

 > > By comparison,
 > >
 > >   x, y += a, b
 > >
 > > is neither more expressive, nor easier to read, nor significantly
 > > harder to type, than
 > >
 > >   x += a
 > >   y += b
 >
 > I agree. I contend that x, y += func(...) is more readable than the three-
 > statement alternative with a namespace pollution.

I'm sure it is.  But what's the context?

That is, just saying you think it's more readable isn't enough.  What
has succeeded in the past (in approximate order of effectiveness) has
been

1.  A reasonably comprehensive survey of the Python stdlib to find use
    cases for the "ugly" construct, and then providing a few "side by
    side" comparisons "before and after" the new syntax, as well as
    statistics for the frequency of the "ugly" construct, and how
    often translation to the new feature improved the code.

2.  A similar exercise for some other large, reasonably well-known
    code base by a respected project.

3.  A few examples from some code base.

Here's an example of the kind of analysis I mean.  I went looking for
examples of swaps in the Python sources by grepping for "sort".  I
found several in Tools/demo/sortvisu.py, but strangely enough,
although it uses sequence assignment for the swap, it does this:

    def swap(self, i, j):
        if i == j: return
        self.countswap()
        item = self.items[i]
        other = self.items[j]
        self.items[i], self.items[j] = other, item
        item.swapwith(other)

The reason is that this is not a sorting application as such, but
rather a demo of tkinter.  So the sort is instrumented in several
ways, and in particular the items being swapped know "where they are"
in the visualization (the item.swapwith(other) call).  Thus the
temporary variables item and other are not spurious.

I'm not sure if I think

    def swap(self, i, j):
        if i == j: return
        self.countswap()
        item, other = self.items[i], self.items[j]
        self.items[i], self.items[j] = other, item
        item.swapwith(other)

is less readable, but I don't think it's more readable.  And with the
instrumentation removed, I'm not sure whether I prefer

    def swap(self, i, j):
        if i == j: return
        self.items[i], self.items[j] = self.items[j], self.items[i]

or

    def swap(self, i, j):
        if i == j: return
        item, other = self.items[i], self.items[j]
        self.items[i], self.items[j] = other, item

It's pretty marginal.  Finally, I think

    if i != j:
        self.items[i], self.items[j] = self.items[j], self.items[i]

inlined instead of

    self.swap(i, j)

perceptibly harms readability, although it would be somewhat faster
due to eliminating the function call, and if speed were at a premium I
would prefer the inline swap to the introduction of any temporary
variables.[1]

My guess is that a lot of realistic cases where you apparently *could*
use augmented assignment of sequences to avoid introducing one or more
temporary variables are going to have some of the same features that
the variables are actually useful beyond the augmented assignment, or
the expressions on one side of the assignment or both are sufficiently
complex that introducing the temporary variable with a descriptive
name improves readability.  But the proof of that will be in doing the
work.

Steve


Footnotes: 
[1]  And if you're reading this, Victor, of course I'd benchmark
before using the less readable version in production. :-)



More information about the Python-ideas mailing list