[Python-ideas] Why operators are useful

Rhodri James rhodri at kynesim.co.uk
Fri Mar 15 15:28:16 EDT 2019

On 15/03/2019 18:54, Raymond Hettinger wrote:
> So, we have to ask whether we're stretching too far from "operators are good" to "we need this operator".  Here are some considerations:
> Frequency of usage:   Math provides ∑ and ∏ because they are common. It doesn't provide a special operator for sqrt(c**2 - b**2) because the latter is less fundamental and less common.  To me, f=d.copy() followed by f.update(e) arises so rarely that an operator isn't warranted.  The existing code is already concise, clear, and rare.

I think the "less fundamental" in your argument is more relevant than 
the "less common".  Mathematicians will cheerfully invent operators for 
whatever is fundamental to their field and then use them twice in a 
paper, but still write out fully common combinations.  I would suggest 
that merging is merging is a fairly fundamental operation for 
dictionaries, so is a good candidate for an operator.

The combination "f=d.copy(); f.update(e)" is rare in my code.  I suspect 
that's partly because it doesn't occur to me that I can do it.  Guido's 
argument about recognisability is strong here.  I know that 
dict.update() exists, and that I can destructively merge dictionaries. 
The extra step of doing the copy first for a non-destructive merge makes 
for a much less memorable pattern, to the point where I just don't think 
of it unless it would be more than usually useful.  "f = d | e" (however 
it gets spelled) is much easier to remember the existence of.

> Familiarity:  We know about + because we use it a lot in addition and concatenation contexts. However, a symbol like ⊗ is more opaque unless we're using it every day for a particular purpose.  To me, the "+" operator implies "add/extend" semantics rather than "replace" semantics.  Successive applications of "+" are never idempotent unless one operand is an identity element.  So for me, "+" isn't familiar for dict merges.  Loosely put, it isn't "plus-like".  I think this is why so many other languages decided not use "+" for dict merges even when that would have been a trivially easy implementation choice.

I'm beginning to be swayed by the arguments that merging is more 
"or-like" and the right analogy is with set union.  Personally I don't 
find "|" for set union at all obvious, but that argument was lost long 
ago, and like I said it's just personal.  I don't have the same problem 
you have with the semantics of "+", but when I was a maths student I was 
used to using "+" as an entirely generic operator not necessarily 
meaning addition, so it's probably just me.

> Obviousness: When working with "+" on numeric types, it is obvious it should be commutative. When using "+" when sequence types, it is obvious that concatenation is non-commutative. When using "+" for mapping types, it is not obvious that it isn't commutative. Likewise, it isn't obvious that "+" is a destructive operation for mappings (consider that adding to a log file never destroys existing log entries, while updating a dict will overwrite existing values).

I suspect this is a bit personal; I had sufficiently evil lecturers in 
my university Algebra course that I still don't automatically take the 
commutativity of "+" over a particular group as a given :-)  Nothing is 
obvious unless you already know it.

(There is a probably apocryphal tale of a lecturer in full flow saying 
"It is obvious that..." and pausing.  He then turned to the blackboard 
and scribbled furiously in one corner for five minutes.  "I was right," 
he said triumphantly, "it is obvious!")

> Harmony: The operators on dict views use "|" but regular dicts would use "+". That doesn't seem harmonious.

Yes, that's probably the killer argument against "+", damn it.

> Impact: When a class in the standard library adds a method or operator, the reverberations are felt only locally.  In contrast, the dict API is fundamental.  Changing it will reverberate for years. It will be felt in the ABCs, typeshed, and every mapping-like object.  IMO such an impactful change should only be made if it adds significant new functionality rather than providing a slightly shorter spelling of something we already have.

I am inclined that adding significant new utility (which this does) is 
also a good enough reason to make such an impactful change.

Rhodri James *-* Kynesim Ltd

More information about the Python-ideas mailing list