
At 09:58 AM 2/27/04 -0500, Phillip J. Eby wrote:
At 12:40 AM 2/27/04 -0500, Glyph Lefkowitz wrote:
(BTW: a common idiom for using interfaces is to scope method names. An optimization I want to add to Twisted at some point is stateless interface-method-call syntax which can do this efficiently, something like: IWhatever.what(x). I believe you should be able to avoid a bunch of Python object allocation overhead by doing it that way. Does PyProtocols provide any such facility?)
Not at the moment. What I'd like to do at some point is add single-dispatch generic functions, though.
Just for the heck of it, I thought I'd try whipping up a single-dispatch generic function using PyProtocols. It turned out to be much easier than I thought; only 19 lines, in fact! from protocols import Protocol, adapt, declareAdapter from new import instancemethod class GenericFunction(Protocol): def __init__(self, defaultFunc=None): Protocol.__init__(self) if defaultFunc is not None: self.add(defaultFunc,[object]) def __call__(__self, self, *__args,**kw): return adapt(self,__self)(*__args,**kw) def add(self,func,forTypes=(),forProtocols=()): declareAdapter( lambda ob,proto: instancemethod(func,ob,type(ob)), provides=[self], forTypes=forTypes, forProtocols=forProtocols ) # Quick test/demo def g(ob): print ob, "is of unknown type" g = GenericFunction(g) class A(object): pass class B(A): pass class C(A): pass def gA(ob): print ob, "is an A" g.add(gA,[A]) def gB(ob): print ob, "is a B" g.add(gB,[B]) # Try it out g(A()) g(B()) g(C()) g([]) # ==== It could probably do with some kind of 'super()'-like mechanism, but that would make for a rather more complex implementation, alas. Still, it's not bad at all and I can think of a few places I might actually use it. For example, it'd be great for writing "visitor" algorithms that need to do different behaviors based on the type or interfaces of the nodes.