[Python-3000] Generic functions

Nick Coghlan ncoghlan at gmail.com
Tue Apr 4 12:12:35 CEST 2006


Ian Bicking wrote:
> As an alternative to adaptation, I'd like to propose generic functions. 
 > I think they play much the same role, except they are much simpler to
 > use and think about.
Unfortunately the rules for choosing *which* implementation to dispatch to, 
even if restricting things to concrete types only, are necessarily complex.
As Walter pointed out, the deliberately simplistic sample code elsewhere in 
this thread dispatches to a different method depending on order of 
registration and hashing idiosyncrasies.
To fix that, you either have to stop permitting subclasses of registered 
argument types, or else you have to define the idea of a "closest" signature 
match, at which point you've been forced to throw "simple" right out the window.
Given this type hierarchy:
 A
 B C
D E F
and a call containing (D(), E(), F()), is the type signature (B, B, C) a 
closer match than the signature (A, E, F)?
In a certain sense, an adapting protocol is just a generic function that only 
permits dispatch of single argument functions based on type of that argument - 
as such, adaptation is necessarily simpler than full generic function support.
To go back to Ian's pretty printing example, here's an implementation of 
pretty printing using an adaptation protocol:
------------pprint.py-----------------
import adaptation
class IPrettyPrintable(adaptation.Protocol):
 def pformat(self, indent, width, depth):
 """Return the pretty representation of the object"""
# Register known pretty printer functions (e.g. for list and dict) here
class PrettyPrinter:
 # Other normal pretty printer methods go here
 def pformat(self, obj):
 printable = IPrettyPrintable(obj) # Permit extension to new types
 return printable.pformat(self.indent, self.width, self.depth)
--------------------------------------
Now all another class would need to do to make itself pretty printable:
------------mymodule.py-----------------
from pprint import IPrettyPrintable
class MyClass(object):
 def pformat(self, indent, width, depth):
 # Do the pretty print operation
 # based on self
 return formatted
IPrettyPrintable.register_type(MyClass) # No adapter needed
--------------------------------------
Suppose, however, I wanted to pretty print someone else's class. That's just 
as easy:
------------mymodule.py-----------------
from pprint import IPrettyPrintable
from their_module import TheirClass
class MyAdapter(object):
 def __init__(self, obj):
 self.obj = obj
 def pformat(self, indent, width, depth):
 # Do the pretty print operation
 # based on self.obj
 return formatted
IPrettyPrintable.register_type(TheirClass, MyAdapter)
--------------------------------------
Cheers,
Nick.
-- 
Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
---------------------------------------------------------------
 http://www.boredomandlaziness.org


More information about the Python-3000 mailing list

AltStyle によって変換されたページ (->オリジナル) /