[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