Fun with decorators and unification dispatch
talin at acm dot org
viridia at gmail.com
Sat Sep 10 20:51:53 EDT 2005
Yes, it was a typo.
Even thought the function has not yet been bound to the name
"Factorial" when it calls the decorator, the function's __name__
attribute is set to it, so I use that to look up the name of the
generic.
Here''s the source for Arity:
def Arity( *pattern ):
"""A function decorator that defines a specific arity of a generic
function. This registers the
specific implementation with the generic function (which must be in
the global scope.)"""
def inner( f ):
if isinstance( f, Function ):
generic = f
f = generic.last_defined
else:
name = f.__name__
if not name in f.func_globals:
raise Exception( "Generic function " + name + " has not
been defined." )
generic = f.func_globals[ name ]
generic.name = name
generic.last_defined = f
generic.add_arity( pattern, f )
return generic
return inner
There's a couple of kludges here:
1) The Generic doesn't know its own name until you define at least one
specialization for it. Otherwise, you would have to say:
Factorial = Function( "Factorial" )
which I consider verbose and redundant.
2) The whole last_defined thing is to allow multiple arities for a
single specialized function. Since the arity normally returns the
generic, and not the specialized func, as the return value, that means
that any additional decorators will be applied to the generic rather
than the specialized func. last_defined is a kludge for getting around
that, but only for decorators that understand the situation.
More information about the Python-list
mailing list