Python and generic programming

Glenn Andreas gandreas at no.reply
Tue Oct 26 11:29:04 EDT 2004


In article <mailman.5295.1098427304.5135.python-list at python.org>,
 Josiah Carlson <jcarlson at uci.edu> wrote:

> Roman Suzi <rnd at onego.ru> wrote:
> 
> > Most Python programs are already kinda generic, yes. But generic
> > programming adds multi-sorted types control and constraints to ensure type
> > safety...
> 
> "kinda generic"?  That is quite the understatement.
> 
> As for "type safety", Python has runtime type checking, and as a
> programmer, if you want to have varying dispatch based on type, you are
> free to do so:
> 
> foo_dispatch = {(int, int):foo_int_int, #some defined function
>                 ...}
> 
> def foo(arg1, arg2):
>     foo_dispatch[(type(arg1), type(arg2))](arg1, arg2)
> 
> 
> With decorator syntax, the above becomes even easier.


How about something like:



class GenericFunction(object):
   def _LookupSignature(cls, sig):
      f = cls._GenericFunctionMap.get(sig,None)
      if f: return f
      # no exact match, fall back to "default"
      # more complex type matching & resolution left as an excerise to
      # the reader
      wild = (None,) * len(sig)
      f = cls._GenericFunctionMap.get(wild,None)
      if f: return f
      raise AttributeError(cls,str(sig))

   _LookupSignature = staticmethod(_LookupSignature)
   def __new__(cls, *params):
      #print "new",cls,params
      sig = tuple([type(x) for x in params])
      return apply(GenericFunction._LookupSignature(cls,sig),params)

def DeclareTypes(function, *typelist):
   import sys
   c = sys._getframe(1)
   cls = globals()[sys._getframe(1).f_code.co_name]
   map = c.f_locals.setdefault('_GenericFunctionMap',{})
   map[tuple(typelist)] = function


class SomeFunction(GenericFunction):
   def IntAndList(i,l):
      print "Int",i,"List",l
   DeclareTypes(IntAndList,int,list)
   
   def IntAndInt(i1,i2):
      print "Int",i1,"Int",i2
   DeclareTypes(IntAndInt,int,int)
   
   def ListAndList(l1,l2):
      print "List1",l1,"List2",l2
   DeclareTypes(ListAndList,list,list)
   
   def AnyAndAny(o1,o2):
      print "o1",o1,"o2",o2
   DeclareTypes(AnyAndAny,None,None)

   def IntOnly(i):
      print "Int",i
   DeclareTypes(IntOnly,int)

SomeFunction(1)
SomeFunction(1,2)
SomeFunction(1,[1,2,3])
SomeFunction("Hello","World")



produces:

Int 1
Int 1 Int 2
Int 1 List [1, 2, 3]
List1 [1, 2] List2 [3, 4]
o1 Hello o2 World


(Again, with decorators, it becomes even cleaner)



More information about the Python-list mailing list