[Python-ideas] PEP: Dict addition and subtraction

Stephen J. Turnbull turnbull.stephen.fw at u.tsukuba.ac.jp
Thu Mar 21 14:10:52 EDT 2019


Chris Angelico writes:

 > ... then, in the interests of productive discussion, could you please
 > explain? What is it about dict addition that makes it harder to
 > understand than other addition?

Antoine didn't say what dict addition does is harder to understand
than other addition.  He said he wants to understand it without
knowing what it does.

I can't say for sure what he means precisely, but I take it that he
wants dict "+" to obey certain regularities that other instances of
"+" do, possibly including outside of Python.  As you'll see I find it
hard to make this precise, but it's a pretty strong feeling for me, as
well.

To me, those regularities include associativity (satisfied in Python
except for floats) and commutativity where possible (integers and I
believe floats do satisfy it, while strings cannot and other sequences
in Python in general do not, although they very often do in
mathematics).

For mappings, the mathematical meaning of "+" is usually pointwise.
This wouldn't make sense for strings (interpreted as mappings from a
prefix of the natural numbers) at all except that by accident in
Python s1[n] + s2[n] does make sense, but not pointwise (because the
length of the result is 2, not 1, for each n).

For sequences in general pointwise doesn't make sense (there's no
restriction to homogeneous sequences, and if there were, like strings
it's not clear that the elements would be summable in an appropriate
sense).  But concatenation always makes sense, especially by analogy
to the somehow (IMO) canonical case of strings.  For sets, the only
plausible interpretation of "addition" is union, but in fact Python
used .add asymmetrically as "add to", not "add together" (self is a
set, argument is a generic object), and the union operator is "|", not
"+".

For dictionaries, neither pointwise addition nor concatenation makes
sense in general, and update is "too asymmetric" for my taste, and has
no analog in the usual algebras of mappings.

In some sense string concatenation, though noncommutative, doesn't
lose information, and it does obey a sort of antisymmetry in that
a + b == reversed(reversed(b) + reversed(a)).  Dictionary update does
lose the original settings.

If people really think it's so important to spell

    d = d0.copy()
    d.update(d1)

as "d0 + d1" despite the noncommutativity (and the availability of
"{**d0, **d1}" for "true" dicts), and by extension the redundant "d |=
d1" for "d.update(d1)", I won't get terribly upset, but I will be sad
because it offends my sense of "beautiful code" (including TOOWTDI,
where "+" for dicts would violate both the "obvious" and the
parenthetical "only one" conditions IMO).  I would consider it a wart
in the same way that many people consider str.join a wart, as it
breaks even more of the regularities I associate with "+" than string
concatenation does.

Again, I don't know what Antoine meant, but I might say the same kind
of thing in the same words, and the above is what I would mean.

Steve


More information about the Python-ideas mailing list