[Python-3000] Discussions with no PEPs
Phillip J. Eby
pje at telecommunity.com
Tue Mar 13 00:40:29 CET 2007
At 07:00 PM 3/12/2007 -0400, Barry Warsaw wrote:
>-----BEGIN PGP SIGNED MESSAGE-----
>Hash: SHA1
>
>On Mar 12, 2007, at 3:33 PM, Phillip J. Eby wrote:
>
> > For maybe 80-90% of the purposes that I originally created
> > PyProtocols for, I have found that "simplegeneric" ( http://
> > cheeseshop.python.org/simplegeneric/ ) is more than adequate -- and
> > it's only 80 lines of code. Guido's more featureful GF prototype
> > isn't that much bigger, I don't believe - heck, it might be smaller
> > if memory serves.
>
>Interesting. Maybe one of the problems here is that we're trying to
>solve different problems. For me one of the most important aspects
>of interfaces is the documentation it gives to people wanting to
>implement alternatives or plugins. Yes, there are other ways to do
>it, but interfaces seems to strike a good balance documentation-in-
>the-code and discoverability.
Remember, len(), iter(), and suchlike are all generic functions -- that
just happen to be implemented using reserved method names instead of a
method registry. Do we need an ILengthMeasurable interface to indicate
that you can call len() on something? Or does it suffice to say, "objects
passed to this API need to be len()-compatible"?
With regard to alternatives and plugins, this is precisely what generic
functions enable, with the added benefit that a third party can provide
(e.g.) the len() implementation for a class, without having to be the
author of it. Yes, adaptation gives you much the same thing, but then,
iter() is a generic adaptation function. (That is, adaptation can be
trivially implemnented using generic functions, but not the other way around).
The principle difference between Python's fixed, built-in generics (len(),
iter(), etc.) and simplegeneric et al is that the former requires you to be
the author of the type in order to implement the behavior. (Some of
Python's stdlib generics like "pickle" do allow you to register
implementations, however.)
Finally, I posted here several months ago a short "Interface" class that
used generic functions for its base - it would let you define generic
functions in its body and then do Zope/PyProtocols-style 'IFoo(bar).foo()'
operations instead of 'foo(bar)'. It was, I believe, only another 30-40
lines of code.
Unless you want all of the fancy introspection features of zope.interface
(which I personally think tempt less-experienced people to write code that
will bite extenders in the butt) or the exotic meta-features of PyProtocols
(which I have found can be replaced by generic functions with "method
combination" support), a few hundred lines of code should be more than
sufficient to implement both generic functions *and* interfaces for the
stdlib's needs.
(Btw, when I say that introspection produces butt-biting code, I mean that
when *I* first started using zope.interface, I created all sorts of horrors
until I realized that interface introspection is an attractive but
unnecessary evil, directly analagous to LBYL vs EAFP and type-testing vs.
duck-typing issues. See
e.g.:
http://www.mockobjects.com/2006/10/tell-dont-ask-and-mock-objects.html and
http://peak.telecommunity.com/protocol_ref/replintrowadapt.html for some
further thoughts on this. Basically, the problem is that if you use
interface detection in order to decide what to do with something, you're
basically taking away the ability for the developer who comes *after* you
to control what happens with the objects they give you. Adaptation and
generic functions don't have this problem.)
More information about the Python-3000
mailing list