Daniel Nouri's Blog

Mon, 15 Jan 2007

Generic functions kick ass

Yesterday, I watched Guido van Rossum's talk about Python 3000 along with some Monty Python sketches that turned up in my search results page. It was quite interesting to see what Python 3.0 will be and what it will not be.

One thing that occured to me some months ago after I watched the TurboGears Ultimate DVD was that those generic functions (in the form of RuleDispatch) are an alternative to adaptation, as it exists in Zope. That is, you could do everything that you wanted to do with adaptation also with generic functions, and that in an arguably less verbose way. Also, Guido explains in his Google talk that adapters are only a special case of generic functions.

I tried it out. In plone.checksum (which is not that interesting by itself), I'm using a generic function instead of adaptation. I have a class called Checksum that returns an md5 checksum in its do_checksum method:

import dispatch

class Checksum:
    @dispatch.generic()
    def do_checksum(self, value):
        """Return md5 object that has the calculated checksum.
        """

You can see that the generic function doesn't actually have an implementation. It's meant to be overloaded like this:

import md5

@Checksum.do_checksum.when('isinstance(value, object)')
def do_checksum(self, value):
    checksum = md5.new()
    checksum.update(str(value))
    return checksum

This is the most general implementation that I could come up with. It'll be called when the argument value is an instance of object, that is, always, unless there's a more specialized generic function. I needed a different implementation of do_checksum for OFS.Image.File, which was easy to hook in:

import OFS.Image.File

@Checksum.do_checksum.when('isinstance(value, OFS.Image.File)')
def do_checksum(self, value):
    checksum = md5.new()
    value = value.data
    if isinstance(value, str):
        checksum.update(value)
    else:
        while value is not None:
            checksum.update(value.data)
            value = value.next
    return checksum

Interfaces are a generally a good thing, but not in this case where we would have to mark the File class just to serve our adaptation.

Guido blogged about adaptation versus generic functions half a year ago. There are also some nice additional links in there.

posted at: 16:25 | 4 comments | category: /devel rss | permanent link | add to del.icio.us or digg it


< January 2007 >
SuMoTuWeThFrSa
  1 2 3 4 5 6
7 8 910111213
14151617181920
21222324252627
28293031   

Feed of all categories: rss rss | atom

Categories: