[Python-3000] Adaptation [was:Re: Iterators for dict keys, values, and items == annoying :)]

Alex Martelli aleaxit at gmail.com
Sat Apr 1 09:42:19 CEST 2006


On Mar 31, 2006, at 10:37 PM, Greg Ewing wrote:

> Alex Martelli wrote:
>> Rather, look (e.g.) at copy_reg  for the typical
>> kludge that's used to reimplement that crucial design  pattern  
>> that is
>> adaptation, over and over and over again.
>
> I don't see what copy_reg has to do with adaptation.

Funny, it seems so blindingly obvious to me, that copy_reg is nothing  
but an ad-hoc implementation of an adaptation registry for one  
special case (while all sorts of special methods perform similar  
tasks in a different way which has the disadvantage of being  
necessarily invasive on the type needing to be adapted).

> What does it adapt, and to what?

It adapts whatever type you're passing to copy_reg.pickle, to the  
protocol "being picklable".

> You seem to be talking about adaptation as if it
> were a general way of mapping a class to anything
> else at all. We already have one of those, it's
> called a dict.

A dict is one fine way to implement an adaptation registry (and I  
believe it's what copy_reg uses for the purpose).

But dicts are fine ways of implementing a huge variety of things,  
from sets (dicts are what we all used to implement sets before module  
sets.py, and later builtin type set, appeared) to classes, instances,  
modules, &c, via their respective __dict__s.  The existence of dicts  
is a laughably feeble excuse to avoid having adaptation in Python's  
standard library, just as it would be to avoid having sets, or  
classes, instances, modules.


> Also, design patterns don't usually have any
> generic implementation, and that's okay. It's
> the reason they're called *design* patterns.

Sure, but as languages get higher-level, and grow powerful libraries  
and frameworks, the repetitive implementations of many patterns  
become part of the language/libraries.

In machine code, circa 1950, "procedure call/return" was a design  
pattern, typically and repetitively implemented by placing the PC  
"somewhere" (that LIFO stacks were the ideal "somewheres" wasn't  
necessarily clear to all implementers back then) and jumping to a  
piece of code which ended by restoring the PC from that "somewhere".   
Since Fortran, languages have embodied the concept; it's not a  
"design pattern" any more, it's a fundamental language concept.

Similarly, at a much higher level, "reactor" is a design pattern, but  
libraries/frameworks such as ACE and Twisted embody it as a  
fundamental concept.  "Mock Object" is another excellent example of a  
DP that (in sufficiently high-level languages) can be, and is,  
usefully embodied in libraries.

>
>> just little hope that adaptation will actually
>> make it into the  language in any 2.* release
>> (for no good reason).
>
> The fact that many people are unconvinced by
> the case made for it so far seems like a good
> reason to me.

In the end, the one person that matters, regarding what gets into  
Python or doesn't, is Guido. When I proposed 'sum', for example,  
everybody else was starting to take potshots at the idea (as usual:  
propose *anything* on python-dev, and there will NEVER be a dearth of  
nay-sayers), but that mattered not a whit, because Guido on that one  
occasion happened to like the idea.

So, the fact that (say) Eby or Martelli or the Twisted folks or the  
Zope folks like adaptation, and Ewing or Bicking or (etc ec) dislike  
it, is really a side show. The point that matters, instead, is  
whether GvR likes it or not. From my viewpoint, the first blocking  
issue is thus that GvR sees adaptation as necessarily requiring the  
existence of interfaces as a formal Python concept -- perhaps because  
that's how PyProtocols and Twisted/Zope deploy it -- and thus won't  
really consider it until he's blessed some specific form of interfaces.

In my view of the issue, while interfaces (or supersets thereof such  
as protocols) are a great setting for adaptation, there is really no  
_need_ to formalize a specific packet of interface features to make  
adaptation already useful.  One could have the protocol specification  
be a *string*, for Pete's sake -- say 'org.python.stdlib.index' to  
require "an integer value usable as index into a sequence",  
'org.python.stdlib.pickle' to require "an object supplying methods  
reductor and constructor", or whatever; and even with such a  
minimalistic, entirely conventions-based approach,  explicitly using  
adaptation would still be practically useful, better than the  
__index__ approach (because it can be noninvasive) and better than  
the copy_reg approach (because it does not require ad-hoc  
reimplementation of registries over and over again).  Blocking the  
consideration of adaptation because the best way to formalize  
interfaces is not yet clear is, in my view, not a good reason.

Ah well, these discussions never produce useful results; indeed,  
that's why I've _almost_ stopped pointing out, each and every time  
yet another ad-hoc (partial, and hobbled) implementation of  
adaptation gets adopted, how the fragmentation could be stopped and  
all such cases usefully unified by accepting protocol-adaptation.  
Once in a while, I'm moved to sing this refrain again, but thanks to  
the ensuing discussion I'm soon reminded that there are many more  
gratifying activities I could pursue instead -- repeated beating of  
my forehead against suitable brick walls spring to mind as being both  
more productive and more fun, for example.


Alex



More information about the Python-3000 mailing list