Wednesday, November 10, 2004

Generic Functions have Landed

Update as of 2004-11-12: Fixed broken API doc link.

I now have a semi-stable generic function API in PyProtocols CVS. This is the same stuff I blogged about on Sunday, but now in a much more usable state, supporting all of Python's esoteric function argument capabilities like default values, variadic and keyword arguments, and even nested tuple arguments. Still no CLOS-style method combination stuff (before/after/around methods and call-next-method), but I'll get to those later.

For now, I'm going to focus on trying to actually use generic functions to refactor some things in PEAK that are a little awkward to do with interfaces, but should be much easier with generic functions. There are lots of areas in PEAK where I've been hesitating to write "yet another configuration registration mechanism" for some special purpose. But PyProtocols' generic functions can be used to implement arbitrary registration policies in place of hand-written registration mechanisms. (Side note: early adopters of Zope X3 may recognize a similarity to Zope X3's "n-tuple adapters". However, n-tuple adapters don't support testing arbitrary conditions, and they use an asymmetric dispatch prioritization rather than the PyProtocols approach of refusing to guess if more than one rule applies, and none are more specific than the others.)

Oh, and I almost forgot, there's also a dispatch.on() decorator that lets you do simple single-dispatch generic functions, and later this week I'll probably write up a "how-to" on implementing the Visitor pattern with them. In the meantime, if you want to experiment, check out the API docs and this mailing list post. Oh, and don't forget, if you're using Python 2.2 or 2.3, you can use this syntax:

def someFunc(self,an_arg):
   """Do something to 'an_arg'"""

Instead of this Python 2.4 syntax:

def someFunc(self,an_arg):
   """Do something to 'an_arg'"""

This is because PyProtocols' function decorators have "magical" backward compatibility support, as long as you use Guido's original decorator syntax. Of course, this "old" syntax will still work in Python 2.4, so don't worry about having to upgrade your PyProtocols decorators when you upgrade to Python 2.4.