[Python-ideas] Revisiting dedicated overloadable boolean operators
Steven D'Aprano
steve at pearwood.info
Sat Aug 4 12:37:52 EDT 2018
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
More information about the Python-ideas
mailing list