On Sat, Aug 04, 2018 at 04:56:56PM +0200, Benedikt Werner wrote: > >I think that before adding more ad hoc binary operators, we ought to > >consider the possibility of custom operators. > > That actually sounds like the most sensible solution so far
Thanks :-) Unfortunately there's a flaw, in that the ~ symbol already means unary bitwise-not, so we can't use ~op for operators. Throwing some ideas out to be shot down: spam !op eggs spam :op eggs spam @op eggs spam ..op eggs > >Although possibly we might choose another pseudo-namespace, to avoid > >custom operators clashing with dunders. Trunders perhaps? (Triple > >underscores?) > > > >Under this scheme, your operators would become: > > > > ~or > > ~and > > ~xor > > > >and call trunders ___or___ etc. > As Dan already pointed out it's very hard to see the difference between > two and three underscores so I don't think "trunders" would be a good idea. Three underscores is 50% longer than two. I don't believe that it is harder to tell the difference between ___ and __ at a glance than it is to tell the difference between __ and _ at a glance, even for those with a mild visual impairment like mine. Unless you're reading and writing code using a proportional font, in which case I have no sympathy. Whatever naming convention we use, it should be a subset of dunders, different from all existing dunders, short enough to avoid being annoying to use, and make up an obviously distinct group. How about this? __o_name__ __o_rname__ > I think it would make sense to instead use a new keyword to define > operators. Maybe something like "defop". I don't think that's a very > common variable or function name. New keywords should be a last resort, only for functionality which requires syntactic support. This doesn't. What will this "defop" keyword do that def doesn't already do? Probably nothing, the methods will be ordinary methods just like __add__ and other operator dunders. And even if we needed some sort of extra functionality, say, registering the operators, we could use a decorator for that. > Example syntax could be: > > class MyInt(int): > defop combine(self, other): > return self, other > > # and now we can use it > x combine y > > # which is equivalent to > x.combine(y) That would mean giving up the ability to detect a whole lot of syntax errors at compile time. Remember that under Python's execution model, the compiler cannot tell in advance which custom operators have been defined and which have not. It has to resolve them at runtime. So the only way we could allow `x combine y` as valid syntax would be if we also allowed errors like `print len alist` as valid syntax. This is why I think that named operators should require a special prefix. Without the prefix, x combine y is a syntax error. But with the prefix, say, x :combine y, the compiler can use a custom byte-code to resolve the operator at runtime. (Of course it will still be a runtime error if neither x nor y define the combine operator.) All this supposes that there is sufficient benefit to allowing custom infix operators, including overridable or/and/xor, which is not yet shown. -- Steve _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/