<div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr">Thank you for this very thoughtful message! It reminded me of my first experience with the old Fortran code. You probably know that earlier in Fortran there were no cryptic shortcuts for writing relational operators: instead of <font face="monospace, monospace">`A >= B`</font>, you had to write <font face="monospace, monospace">`A .GE. B`</font>, or as many often wrote this without spaces<font face="monospace, monospace"> `A.GE.B`</font>. Even after a decent time, I still mentally stop and linger on these places. It's amazing that, before your message, I never thought about the difference in perception between<font face="monospace, monospace"> `>=`</font> and <font face="monospace, monospace">`.GE.`</font>. It seems to me that, from the perception point of view, the main difference is that <font face="monospace, monospace">`A .GE. B`</font> consists of readable characters and therefore we try to read them, while <font face="monospace, monospace">`A >= B`</font> is perceived as a single structure (picture) due to unreadable <font face="monospace, monospace">`>=`</font>. And our brain is much more better at pattern matching than when reading. The same is true in Python in the difference between the operator and method forms: <font face="monospace, monospace">`a >= b` </font>and <font face="monospace, monospace">`a.__ge__(b)`</font>. If we draw an analogy for dictionaries between:<br></div><div dir="ltr"><br></div><div dir="ltr"><div dir="ltr"><font face="monospace, monospace">a | b   # (my preference) over `a + b`   (1)</font></div><div dir="ltr"><br></div><div dir="ltr">and</div><div dir="ltr"><br></div><div dir="ltr"><font face="monospace, monospace">d = d1.copy()                            (2)</font></div><div dir="ltr"><font face="monospace, monospace">d = d.update(d2)</font></div><div dir="ltr"><font face="monospace, monospace"><br></font></div><div dir="ltr"><div dir="ltr" style=""><font face="arial, helvetica, sans-serif">The (1) is perceived as a picture, while (2) is perceived as a short story. And you have to read it, and spend some extra time, and spend some extra energy. English is not my mother tongue, so I'm not sure that my words correctly convey the meaning of the analogy. </font></div><div dir="ltr" style=""><font face="arial, helvetica, sans-serif"><br></font></div><div dir="ltr" style=""><font face="arial, helvetica, sans-serif">Offtopic: To be honest, the idea of </font><font face="monospace, monospace">`+`</font><font face="arial, helvetica, sans-serif"> operator overloading for something non numeric still does not fully fit in my numerically oriented mind. If I started from the beginning, I would introduce a special dunder for concatenation (</font><font face="monospace, monospace">__concat__</font><font face="arial, helvetica, sans-serif">) with the corresponding operator, something like </font><font face="monospace, monospace">seq1 .. seq2</font><font face="arial, helvetica, sans-serif"> or</font><font face="monospace, monospace"> seq1 ~ seq2</font><font face="arial, helvetica, sans-serif">. But that ship has long sailed.</font></div><div dir="ltr" style=""><font face="arial, helvetica, sans-serif"><br></font></div><div style=""><font face="arial, helvetica, sans-serif">With kind regards,</font></div><div style=""><font face="arial, helvetica, sans-serif">-gdg</font></div><div dir="ltr" style=""><font face="arial, helvetica, sans-serif"><br></font></div><div dir="ltr" style=""><font face="arial, helvetica, sans-serif"><br></font></div></div><div dir="ltr"><font face="monospace, monospace"><br></font></div></div></div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">пт, 15 мар. 2019 г. в 20:52, Guido van Rossum <<a href="mailto:guido@python.org">guido@python.org</a>>:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>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.</div><div><br></div><div>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.</div><div><br></div><div>For mathematicians, operators are essential to how they think. Take a simple operation like adding two numbers, and try exploring some of its behavior.</div><div><br></div><div>    add(x, y) == add(y, x)    (1)</div><div><br></div><div>Equation (1) expresses the law that addition is commutative. It's usually written using an operator, which makes it more concise:</div><div><br></div><div>    x + y == y + x    (1a)</div><div><br></div><div>That feels like a minor gain.</div><div><br></div><div>Now consider the associative law:</div><div><br></div><div>    add(x, add(y, z)) == add(add(x, y), z)    (2)</div><div><br></div><div>Equation (2) can be rewritten using operators:</div><div><br></div><div>    x + (y + z) == (x + y) + z    (2a)</div><div><br></div><div>This is much less confusing than (2), and leads to the observation that the parentheses are redundant, so now we can write</div><div><br></div><div>    x + y + z    (3)</div><div><br></div><div>without ambiguity (it doesn't matter whether the + operator binds tighter to the left or to the right).</div><div><br></div><div>Many other laws are also written more easily using operators.  Here's one more example, about the identity element of addition:</div><div><br></div><div>    add(x, 0) == add(0, x) == x    (4)</div><div><br></div><div>compare to</div><div><br></div><div>    x + 0 == 0 + x == x    (4a)</div><div><br></div><div>The general idea here is that once you've learned this simple notation, equations written using them are easier to *manipulate* than equations written using functional notation -- it is as if our brains  grasp the operators using different brain machinery, and this is more efficient.</div><div><br></div><div>I think that the fact that formulas written using operators are more easily processed *visually* has something to do with it: they engage the brain's visual processing machinery, which operates largely subconsciously, and tells the conscious part what it sees (e.g. "chair" rather than "pieces of wood joined together"). The functional notation must take a different path through our brain, which is less subconscious (it's related to reading and understanding what you read, which is learned/trained at a much later age than visual processing).<br></div><div><br></div><div>The power of visual processing really becomes apparent when you combine multiple operators. For example, consider the distributive law:</div><div><br></div><div>    mul(n, add(x, y)) == add(mul(n, x), mul(n, y))  (5)</div><div><br></div><div>That was painful to write, and I believe that at first you won't see the pattern (or at least you wouldn't have immediately seen it if I hadn't mentioned this was the distributive law).<br></div><div><br></div><div>Compare to:</div><div><br></div><div>    n * (x + y) == n * x + n * y    (5a)</div><div><br></div><div>Notice how this also uses relative operator priorities. Often mathematicians write this even more compact:</div><div><br></div><div>    n(x+y) == nx + ny    (5b)</div><div><br></div><div>but alas, that currently  goes beyond the capacities of Python's parser.</div><div><br></div><div>Another very powerful aspect of operator notation is that it is convenient to apply them to objects of different types. For example, laws (1) through (5) also work when n, x, y and z are same-size vectors (substituting a vector of zeros for the literal "0"), and also if x, y and z are matrices (note that n has to be a scalar).</div><div><br></div><div>And you can do this with objects in many different domains. For example, the above laws (1) through (5) apply to functions too (n being a scalar again).</div><div><br></div><div>By choosing the operators wisely, mathematicians can employ their visual brain to help them do math better: they'll discover new interesting laws sooner because sometimes the symbols on the blackboard just jump at you and suggest a path to an elusive proof.</div><div><br></div><div>Now, programming isn't exactly the same activity as math, but we all know that Readability Counts, and this is where operator overloading in Python comes in. Once you've internalized the simple properties which operators tend to have, using + for string or list concatenation becomes more readable than a pure OO notation, and (2) and (3) above explain (in part) why that is.<br></div><div><br></div><div>Of course, it's definitely possible to overdo this -- then you get Perl. But I think that the folks who point out "there is already a way to do this" are missing the point that it really is easier to grasp the meaning of this:<br></div><div><br></div><div>    d = d1 + d2</div><div><br></div><div>compared to this:<br></div><div><br></div><div>    d = d1.copy()</div><div>    d = d1.update(d2)<br></div><div><br></div><div>and it is not just a matter of fewer lines of code: the first form allows us to use our visual processing to help us see the meaning quicker -- and without distracting other parts of our brain (which might already be occupied by keeping track of the meaning of d1 and d2, for example).</div><div><br></div><div>Of course, everything comes at a price. You have to learn the operators, and you have to learn their properties when applied to different object types. (This is true in math too -- for numbers, x*y == y*x, but this property does not apply to functions or matrices; OTOH x+y == y+x applies to all, as does the associative law.)</div><div><br></div><div>"But what about performance?" I hear you ask. Good question. IMO, readability comes first, performance second. And in the basic example (d = d1 + d2) there is no performance loss compared to the two-line version using update, and a clear win in readability. I can think of many situations where performance difference is irrelevant but readability is of utmost importance, and for me this is the default assumption (even at Dropbox -- our most performance critical code has already been rewritten in ugly Python or in Go). For the few cases where performance concerns are paramount, it's easy to transform the operator version to something else -- *once you've confirmed it's needed* (probably by profiling).<br></div><div><br>-- <br><div dir="ltr" class="gmail-m_4838327696295458286gmail_signature">--Guido van Rossum (<a href="http://python.org/~guido" target="_blank">python.org/~guido</a>)</div></div></div>
_______________________________________________<br>
Python-ideas mailing list<br>
<a href="mailto:Python-ideas@python.org" target="_blank">Python-ideas@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/python-ideas" rel="noreferrer" target="_blank">https://mail.python.org/mailman/listinfo/python-ideas</a><br>
Code of Conduct: <a href="http://python.org/psf/codeofconduct/" rel="noreferrer" target="_blank">http://python.org/psf/codeofconduct/</a><br>
</blockquote></div>