Python and generic programming

Carl Banks imbosol at aerojockey.com
Sun Nov 21 18:46:48 EST 2004


"Jive" <someone at microsoft.com> wrote in message news:<suRnd.4852029$ic1.459375 at news.easynews.com>...
> When you define a function in Python, you are (in effect) defining many
> functions, just as Issac says.  What the byte codes eventually do depends on
> type information that is acted on at runtime.  C++ has a mechanism
> (templates) for acting on the type information similarly, but at compile
> time.  However, a modern C++ compiler can do something beyond that.  It can
> recognize special cases (which the programmer must code for) and use a
> different functional form (template) for the special case than for the
> generic case.  Both STL and BGL use the mechanism extensively.


This doesn't look too hard.  Untested, cause I don't have Python 2.4
yet:

    def generic(genfunc):
        speclist = []
        def wrapf(arg):
            for (specfunc,typ) in speclist:
                if isinstance(arg,typ):
                    return specfunc(arg)
            return genfunc(arg)
        wrapf.speclist = speclist
        wrapf.func_name = genfunc.func_name # isn't this ok in 2.4?
        return wrapf

    def specializes(genf,typ):
        def spd(specf):
            genf.speclist.append((specf,typ))
            return specf
        return spd

    # so my European friends don't get too upset
    specialises = specializes

Then:

    @generic
    def some_function(arg):
        print "generic"

    @specializes(some_fuction,int)
    def some_int_specific_function(arg):
        print "int-specific"

Whence calling some_function('abc') prints "generic", and calling
some_function(123) prints "int-specific".

Obviously this example could use lots of improvement.  It only works
for functions of one argument, and it could probably do better than a
linear search through the type-dispatch list.  But it does show how it
can be done.

A couple things: I personally have a distaste for specializations,
because of the easy possibily that what is supposed to be an
optimized, but equivalent, version of the generic function does
something different (intentionaly or not).  IMO, that's much too stiff
a price for a premature optimization.  They should rarely be used
outside the final stages of development.  Or if you WANT the
specialization to behave differently, you ought to be using regular
old polymorphism.

Having said that, if you're going to use specializations, then the way
I did it above, by explicitly defining functions as generic and
specialized, is a much better way to do it than in C++ IMO.  At least
then you get advance warning of any surprises.  "Explicit is better
than implicit", 'n at.  By not supporting implicit specializations, I
think Python's doing a good job.


-- 
CARL BANKS



More information about the Python-list mailing list