Re: Overloading function calls

Tim Peters (tim@ksr.com)
Sun, 05 Jun 94 17:25:31 -0400

Attached is a rudimentary "function overloading class", that allows
registration of <implementing_function, type_signature> pairs. A type
signature is a tuple returned by the "sig" function, and uses a notion of
type fiddled, as Marc suggested, to distiguish among instances of user-
defined classes. E.g., this:

class A: pass
class B: pass
a1 = A(); a2 = A()
b1 = B(); b2 = B()

ofunc = Overload()
ofunc.register( lambda x,a: 'float x A', sig(1.,a2) )
ofunc.register( lambda x, b: 'float x B', sig(1.,b2) )
ofunc.register( lambda i: '{int, long}', [sig(1), sig(1L)] )
ofunc.register( lambda a,b: 'A x B', sig(a1,b1) )
ofunc.register( lambda b,a: 'B x A', sig(b1,a1) )
ofunc.register( lambda ab1,ab2: '{A x A, B x B}', [sig(a1,a1), sig(b2,b1)] )
ofunc.register( lambda: 'void', [()] )

# if a __call__ special method is introduced, these could be
# print ofunc(1)
# etc
print ofunc.call(1)
print ofunc.call(a1, b2)
print ofunc.call(a2, a2)
print ofunc.call(b2, a2)
print ofunc.call(32L * 54)
print ofunc.call(1.0, b1)
print ofunc.call()
print ofunc.call(1L, b1)

prints this:

{int, long}
A x B
{A x A, B x B}
B x A
{int, long}
float x B
void
Traceback (innermost last):
...
TypeError: unregistered signature (<type 'long int'>, <class B at 657b8>)

By modifying an executable prototype, it's possible to formulate proposed
rules precisely and give 'em a test run.

observingly y'rs - tim

Tim Peters tim@ksr.com
not speaking for Kendall Square Research Corp

class C: pass
_it = type(C())
del C

def _type(x):
t = type(x)
if t is _it: t = x.__class__
return t

def sig( *values ):
return list2tuple( map(_type, values) )

def list2tuple(list):
tup = ()
for x in list: tup = tup + (x,)
return tup

class Overload:
def __init__(self):
self.sig2func = {}

def register(self, func, sig_or_sig_list):
if type(sig_or_sig_list) == type(()):
sig_or_sig_list = [sig_or_sig_list]
for sig in sig_or_sig_list:
self.sig2func[sig] = func

def call(self, *args):
signature = apply(sig, args)
try:
func = self.sig2func[signature]
except KeyError:
raise TypeError, 'unregistered signature ' + `signature`
return apply(func, args)

# end of module