[Python-ideas] Why operators are useful

Jonathan Fine jfine2358 at gmail.com
Fri Mar 15 15:05:29 EDT 2019


Guido wrote:

> There's been a lot of discussion about an operator to merge two dicts. I participated in the beginning but quickly felt overwhelmed by the endless repetition, so I muted most of the threads.

> But I have been thinking about the reason (some) people like operators, and a discussion I had with my mentor Lambert Meertens over 30 years ago came to mind.

> For mathematicians, operators are essential to how they think.

I agree about the endless repetition. I hope Steven D'A is making good
progress with the revised PEP. I think that could help us focus
discussion.

A few days ago, I drafted but did not send a post on binary operators.
Prompted by Guido's helpful post, I'm appending it below. My approach
and opinions are not the same as Guido's, but have much in common.
Perhaps later, I'll clarify where I agree with Guido, and where my
opinions differ.

Certainly, I think we have in common an emphasis on usability and in
particular readability of code.

====================================================
SUBJECT: Naming things: would having more binary operators help?

SUMMARY
I'm refocusing our earlier discussion on binary operators. I suggest
we discuss the question:
Providing more binary operators. When would this make naming things
this easier? And when harder?

THE PROBLEM
Naming things is hard.

For example https://hilton.org.uk/blog/why-naming-things-is-hard
"Naming is communication. Bad names prevent code from clearly
communicating its intent, which is why code with obfuscated names is
spectacularly hard to understand. The compiler might not care, but the
humans benefit from naming that communicates effectively."

AN EXAMPLE
One person wrote:
using + to merge dicts is simple, non-disruptive, and unlikely to
really confuse anyone - so why not?

Another person proposed:
d1 << d2 merges d2 into a copy of d1 and returns it, with keys from d2
overriding keys from d2.

A third person wrote:
"|" (especially "|=") *is* suitable for "update"
[So] reserve "+" for some alternative future commutative extension

A fourth person provided a '+' operator on a subclass of dict, that
merged items using a special addition on numeric values.

A fifth person suggested adding arrow operators, with symbols '->' and '<-'.

A six person said that '<-' would break code valid such as '-2<-1'.

A seventh person noted that annotations already use '->' as a symbol.

An eighth person said the infix module allows you to write a @cup@ b

An nineth person (me) will soon suggest that we add dict.gapfill
    current.update(changes) # If conflict, prefer value in changes.
    options.gapfill(defaults) # If conflict, prefer value in options.
(and so '+' or '|' for update not so clear).

BENEFITS OF BINARY OPERATORS
Binary operators, such as '+' allow us to write:

    c = a + b # Infix notation
    a += x # mutation or augmented assignment
    a[key] += x # as above, but 'in place'

At school, when we learn arithmetic, we learn it using infix notation.
   Two plus two is four.
   Seven times eight is fifty-six.

I think the above indicates the benefits of binary operators.
Particular when binary operation does not mutate the operands.

DIFFICULTIES
Sometimes, having few names to choose makes naming things easier.
That's obvious. Sometimes, having a wider choose makes naming things
easier. Think Unicode's visually similar characters.

At present, Python has 20 operators, the majority being binary
evaluation operators.
https://docs.python.org/3/reference/lexical_analysis.html#operators
    +       -       *       **      /       //      %      @
    <<      >>      &       |       ^       ~
    <       >       <=      >=      ==      !=

The last row gives the (binary) comparison operators. The symbols '^'
and '~' are unary operators. For clarity, I'm thinking of the binary
evaluation operators, or in other words '+' through to '|'.

Aside: '+' and '-' can be used as binary and unary operators.
    >>> 5 + -- +++ ---- + ------ - 4
    1

ONE SUGGESTION
The twelve binary evaluation operators sounds a lot, but perhaps some
users will need more.  Even it might be nice if the same symbol didn't
have too many different meanings. Python2 used '/' for both float and
integer division. To reduce cognitive overload, Python3 introduced
'//' for integer division.

    >>> 4.3 // 2.1
    2.0

For example https://oeis.org/wiki/List_of_LaTeX_mathematical_symbols#Arrows
lists 10 types of horizontal arrow, and 6 types of vertical arrow.

Providing more binary operators is the motivation for my proposal

     # https://en.wikipedia.org/wiki/Inclusion%E2%80%93exclusion_principle
     len( A @cup B) == len( A ) + len( B ) - len( A @cap B )

(By the way, we might prefer 'union' and 'intersection' to 'cup' and
'cap'. Also there are alternatives, such as using $ instead of @, or
using Unicode Math Characters.)

If there is a shared wish to have more binary operators, it might then
be useful to discuss how.

DISCUSSION QUESTION
Please discuss:  Providing more binary operators. When would this make
naming things this easier? And when harder?

By the way, naming things is mainly a human usability issue. The
computer doesn't care about this. Even if we use only the current
binary operators, this discussion should help us understand better
naming and usability.

--
Jonathan


More information about the Python-ideas mailing list