[Python-ideas] Why operators are useful
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