Symmetric vs asymmetric symbols (was PEP 572: Do we really need a ":" in ":="?)
On Fri, Jul 6, 2018 at 12:48 PM, Alexander Belopolsky
Python really has a strong C legacy and this is the area where I agree that C designers made a mistake by picking a symmetric symbol (=) for an asymmetric operation. On top of that, they picked an asymmetric digraph (!=) for a symmetric operation as well and Python (unfortunately) followed the crowd and ditched a much better alternative (<>). My only hope is that Python 4.0 will allow ← to be used in place of either = or :=. :-)
Interesting. Looking over Python's binary operators, we have: |, ^, &, +, *: symmetric (on ints) -, /, //, **: asymmetric <, >: mirrored operations <=, >=: mirrored operations but not reflected <<, >>: non-mirrored asymmetric and, or: technically asymmetric but often treated as symmetric in, not in: asymmetric is, is not: symmetric Which ones ought to have symmetric symbols, in an ideal world? Should <= and >= be proper mirrors of each other? Are << and >> confusing? Is it a problem that the ** operator is most decidedly asymmetric? Personally, I'm very happy that the operators use the same symbols that they do in other languages - U+002B PLUS SIGN means addition, for instance - and everything else is secondary. But maybe this is one of those "hidden elegances" that you're generally not *consciously* aware of, but which makes things "feel right", like how Disney's "Moana" has freedom to the right of the screen and duty to the left. Are there languages where symmetric operations are always represented with symmetric symbols and vice versa? ChrisA
On 06.07.2018 7:02, Chris Angelico wrote:
On Fri, Jul 6, 2018 at 12:48 PM, Alexander Belopolsky
wrote: Python really has a strong C legacy and this is the area where I agree that C designers made a mistake by picking a symmetric symbol (=) for an asymmetric operation. On top of that, they picked an asymmetric digraph (!=) for a symmetric operation as well and Python (unfortunately) followed the crowd and ditched a much better alternative (<>). My only hope is that Python 4.0 will allow ← to be used in place of either = or :=. :-) Interesting. Looking over Python's binary operators, we have:
|, ^, &, +, *: symmetric (on ints) -, /, //, **: asymmetric <, >: mirrored operations <=, >=: mirrored operations but not reflected <<, >>: non-mirrored asymmetric and, or: technically asymmetric but often treated as symmetric in, not in: asymmetric is, is not: symmetric
Which ones ought to have symmetric symbols, in an ideal world? Should <= and >= be proper mirrors of each other? Are << and >> confusing? Is it a problem that the ** operator is most decidedly asymmetric?
Personally, I'm very happy that the operators use the same symbols that they do in other languages - U+002B PLUS SIGN means addition, for instance - and everything else is secondary. But maybe this is one of those "hidden elegances" that you're generally not *consciously* aware of, but which makes things "feel right", like how Disney's "Moana" has freedom to the right of the screen and duty to the left. Are there languages where symmetric operations are always represented with symmetric symbols and vice versa?
Nothing like that. The connotations for the symbols rather draw from other fields that we're familiar with. Primarily math (that everyone has studied at school -- this is also the reason why we use infix notation even though the postfix one allows to ditch braces); in particular, % draws from ÷ (division sign), / from fraction sign; & is from English; !, | and ^ are a mash from "the closest unused symbols on keyboard" to symbols from logic algebra: ¬ (https://en.wikipedia.org/wiki/Negation),∨ {\displaystyle \lor } ∨ (https://en.wikipedia.org/wiki/Logical_disjunction), ∧ (https://en.wikipedia.org/wiki/Logical_conjunction), ↑ or | (https://en.wikipedia.org/wiki/Sheffer_stroke), ↓ (https://en.wikipedia.org/wiki/Peirce's_arrow); "!=" reads literally "not equal" ( ! is "not", = is "equal" ) (while "<>" reads "less or greater" which is mathematically not equivalent to that: not everything has a defined ordering relation. "<>" draws from BASIC AFAIK which was geared towards regular users who don't deal with advanced mathematics.)
ChrisA _______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/vano%40mail.mipt.ru
Ivan Pozdeev via Python-Dev wrote:
(while "<>" reads "less or greater" which is mathematically not equivalent to that: not everything has a defined ordering relation.
I think this is a silly argument against "<>". If we're going to try to assign meaning to individual characters in an operator, we could equally well say that "!" on its own should mean "not", which it doesn't in Python. Whereas "~" does, kind of, so "not equal" should be spelled "~=".
"<>" draws from BASIC AFAIK which was geared towards regular users who don't deal with advanced mathematics.)
Criticising something because it comes from BASIC smacks of snobbery. Anyway, it's also used by a number of entirely respectable languages such as Pascal and SQL. And what proportion of Python users deal with advanced mathematics? -- Greg
On Sat, Jul 07, 2018 at 01:03:06PM +1200, Greg Ewing wrote:
Ivan Pozdeev via Python-Dev wrote:
(while "<>" reads "less or greater" which is mathematically not equivalent to that: not everything has a defined ordering relation.
I think this is a silly argument against "<>".
While I agree with your conclusions, I'd just like to point out that given the existence of float NANs, there's a case to be made for having separate <> and != operators with != keeping the "not equal" meaning and the <> operator meaning literally "less than, or greater than". py> NAN != 23 True py> NAN < 23 or NAN > 23 False (I'm not making the case for this, just pointing out that it exists...) There would be precedent too: at least one of Apple's SANE maths libraries back in the 1990s had a full set of NAN-aware comparison operators including IIRC separate "not equal" and "less than or greater than" comparisons. But I think this is a corner of IEEE-754 esoterica that probably doesn't need to be a builtin operator :-) Also: py> from __future__ import barry_as_FLUFL py> 23 <> 42 True -- Steve
.... I'd just like to point out that given the existence of float NANs, there's a case to be made for having separate <> and != operators with != keeping the "not equal" meaning and the <> operator meaning literally "less than, or greater than".
py> NAN != 23 True py> NAN < 23 or NAN > 23 False
(I'm not making the case for this, just pointing out that it exists...)
There would be precedent too: at least one of Apple's SANE maths libraries back in the 1990s had a full set of NAN-aware comparison operators including IIRC separate "not equal" and "less than or greater than" comparisons.
But I think this is a corner of IEEE-754 esoterica that probably doesn't need to be a builtin operator :-)
The 754 standard's section 5.7 (Comparisons) defines 26(!) distinct comparison predicates. I bet SANE supplied all of them - and quite
[Steven D'Aprano] possibly nothing else in the world ever bothered (the standard _required_ only a relative few of them). I never had the slightest interest in garbaging-up Python with syntax for all those, so never even mentioned it in the early days. My secret plan ;-) was that if someone agitated for it enough to sway Guido, I'd add a math.ieee_compare(x, y, raise=False) function that returned one of the four bit constants IEEE_(LESS, EQUAL, GREATER, UNORDERED} (with values 1, 2, 4, 8), and raised some spelling of "invalid operation" iff `raise` was True and at least one of the comparands was a NaN. That's enough to build any of the standard's predicates (and a few more essentially useless ones, like "always true"). Then, e.g., for your <> above def "<>"(x, y): return ieee_compare(x, y) & (IEEE_LESS | IEEE_GREATER) != 0 and != above would add IEEE_UNORDERED to the bits checked in that. Then it's equal easy to build oddballs like "unordered or greater" and "only equal but raise an exception if a NaN is compared" too. I've been quite relieved that, after all these years, nobody else seemed to care about this either :-)
participants (5)
-
Chris Angelico
-
Greg Ewing
-
Ivan Pozdeev
-
Steven D'Aprano
-
Tim Peters