On Wed, Jun 5, 2019 at 6:08 PM Yanghao Hua firstname.lastname@example.org wrote:
On Wed, Jun 5, 2019 at 12:52 AM Greg Ewing email@example.com wrote:
Yanghao Hua wrote:
Did Guido say "user defined syntax" or "user defined operator"? ... for me defining new operator is different
To my mind it's not that much different. A reader encountering an unfamiliar operator is pretty much faced with a new piece of syntax to learn. Its spelling gives little to no clue as to its meaning, it precedence in relation to other operators is not obvious, etc.
The way scala allows user to define new operator is really elegant,
There are some differences between Python and Scala that present practical difficulties here. Some kind of declaration would be needed to define its arity, precedence and corresponding dunder method. This is no problem in Scala because it analyses imported code at compile time. But the Python compiler only sees the module being compiled, so it has no ability to import these kinds of declarations from another module.
My understood how scala achieves this is, whenenver it sees "taken1 token2 token3" kind of expression, it does token1.token2(token3). So it was assumed token2 is a method of token1 and it always takes one argument.
With my very limited understanding of cpython internals (at least when I implement <==) it seems cpython is searching for an operator and then translates it into a method call on the objects, so what if instead of telling e.g. python to search __add__ method call, it should search int.+ (the "+" method call) instead? Not sure if this helps at all I believe there are tons of other problems too. This is definitely NOT an easy thing to add post-fact if not thought through from the very beginning.
Part of the reason you can't just treat the + operator as a method call is that there are reflected methods. Consider:
class Int(int): def __radd__(self, other): print("You're adding %s to me!" % other) return 1234
x = Int(7) print(x + 1) print(1 + x)
If these were implemented as x.__add__(1) and (1).__add__(x), the second one would use the default implementation of addition. The left operand would be the only one able to decide how something should be implemented.