Directly Overloading ==

Alex Martelli aleaxit at yahoo.com
Wed Sep 13 10:49:02 CEST 2000


[posted & mailed, as requested]

"Terry Hancock" <hancock at earthlink.net> wrote in message
news:39BECD50.CF19C401 at earthlink.net...
> Can you do it?

Not the way you desire, no.

> IMHO, it would be extremely convenient to overload
> the "==" operator directly, to change it to
> return a fuzzy logic value indicating the
> *degree* of equality rather than absolute
> equality (which as with float values is pretty
> pointless with fuzzy logic).

This would make the overloaded == completely unusable
in all existing contexts, that expect it to return a
value directly usable as true/false.  For example, if
a if an object and b a list,
    if a in b:
        print "it's there"
compares a for equality (with ==) with each item in b,
and stops when an == returns a "true" value (or when b
is exausted, in which case the 'a in b' test returns
false).  The existing == is also used when an object is
a key in a dictionary, and again it needs a true/false
value (pretty obviously, wouldn't you say?).  And so on,
and so forth.

Why break so many things just to get the infix-operator
syntax sugar for your fuzzy comparisons... just define
a function or method that does what you desire, and call
it with the appropriate syntax.  Nobody has ever decreed
that 'comparisons' which are not really boolean yes/no
comparisons must use '==', or, use infix syntax at all.

Polymorphism of all kinds is just nice and dandy, and I'm
a big fan of it, but if it's to be useful it must respect
the _substitution principle_ (related to Liskov's rule);
and an operator that returns non-boolean values will never
be substitutable for one that returns boolean values.


> This would make it possible to write an expression
> like:
>
> c = (a == b)
>
> where c acquires a fuzzy value indicate the correlation
> of a and b.  This will actually be equivalent to
>
> c = not (a xor b)
>
> (after properly overloading not and xor with their fuzzy
> logic counterparts) but be a lot easier to understand.

And much easier yet will be:

    c = fuzzy.eq(a,b)

or however else you want to name this.  The redundant
parentheses you added to

    c = a == b

still don't make it as readable as a named-function call
(in my example, function eq from module fuzzy) to perform
a "fuzzy equality comparison".  Actually it seems to me
that the 'equality' is really a misnomer here, and 'fuzzy
comparison' or 'fuzzy correlation' much better, so:

    c = fuzzy.cmp(a,b)

or

    c = fuzzy.corr(a,b)

or whatever.  You just don't have the same latitude for
proper, clear naming with infix operators, as you do with
named functions.


> It's particularly sensible when used with the defuzzifying
> operations in an expression:
>
> if perchance( a == b ) : ...
>
> where "perchance()", along with "absolutely()" is one
> of several ways to convert a fuzzy expression to crisp
> logic, using in this case a weighted random number method.

So, assuming you have a
    from fuzzy import *
at the top (surely 'perchance' is in module 'fuzzy'?),

    if perchance(eq(a,b)):
        ...

with no loss of readability (and a gain in generality).


> It might find similar uses in scientific programming,
> where it could be used to replace the obnoxious
> comparisons that usually have to be used in iteration
> tests:
>
> if target - TOLERANCE < value < target + TOLERANCE : ...

    if within_bounds(value, target, TOLERANCE):
        ...

is what I'll do (and the test will more often be one of
relative distance than of absolute one, but that's another
issue).  Feels much better to me than:

    if tolerably(value==target, TOLERANCE):
        ...

> So, back to the question:
>
> 1) Can you do it?

No.

> 2) If not, will you ever be able to? (Or, put another
> way, could I find out how to implement it and submit
> a patch?).

I earnestly hope no such breakage of operator == will
be allowed in the future.  Of course, only Tim (channeling
Guido) can say for sure.

> 3) If it's really impossible, what's the most sensible
> work-around?

Named functions, IMHO.  Using a named method on your
specific kinds of objects is less general.  A named
function can be polymorphic on every kind of things,
and delegate to a named method iff that method is
available, otherwise resolving things itself if that's
feasible or else raising an exception as a last resort.

You can easily prototype this in Python, then, once you
have the interface you want, profile typical usages, and,
should the resulting performance not be what you need,
provide a C-written extension to make it fast.


> Please CC me as I'm not yet on the list (I tried, but
> the server seems to be pretty busy right now).

You may want to look into news:comp.lang.python, which
is available from a lot of servers (all that carry a good
Usenet feeds).  I personally prefer newsgroups to mailing
lists when I have a choice; here, I do, since the group
and the list are supposed to exactly mirror each other.


Alex






More information about the Python-list mailing list