[Python-3000] Adaptation: T->P vs P->P
Nick Coghlan
ncoghlan at gmail.com
Tue Apr 4 14:40:09 CEST 2006
Tim Hochberg wrote:
> Michael Chermside wrote:
>> Tim's proposal (if I understand it correctly) depends on transitivity --
>> his idea is to have the class authors register as satisfying a small
>> number of widely-known protocols (Psrc in his case),
>>
> Yes.
>
>
>> then use transitivity
>> to infer ways to satisfy less well-known protocols.
>>
> No.
>
> All I'm saying is that every object is associated with zero or more
> protocols. The details of this association are TBD, but look here for
> one simple/simplistic approach:
> http://members.cox.net/~tim.hochberg/adaption2.py
> Adapters are always between two protocols. There is not attempt at
> transitivity at all. So adapt looks like this:
>
> def adapt(obj, Pdest, registry=_global_registry):
> protocols = find_protocols(obj)
> if Pdest in protocols: # Always return the original object if it
> satisfies Pdest
> return obj
> for Psrc in protocols:
> adapter = registry.get((Psrc,Pdest), None)
> if adapter is not None:
> return adapter(obj)
> raise ValueError('adapter not found')
>
The interesting thing about this T->P1->P2 system is that it is based on two
rules:
1. A type can be registered as implementing a protocol
2. A protocol can be registered as adapting to another protocol
The annoyance is that there is then no way to register a direct adaptation
from MyType to P2. Instead, you have to define a "IMyType" interface that
"MyType" implements, and then adapt from IMyType to P2. Not exactly the most
convenient API ever :)
However, consider the transitive chain involved when adapting an object O of
type T, which implements protocol P1, to protocol P2:
P2 has an adapter A registered to convert from protocol P1
Type T is registered as implementing protocol P1
Object O is an exact instance of either type T or a subclass of type T
Therefore A(O) can be used to adapt object O to protocol P2.
The "registered as implementing" transitive step is intriguingly similar to
the transitive step in getting from the type T to its instance O. Since class
inheritance is assumed to be lossless (interface-wise) unless told otherwise,
it doesn't matter whether or not O is an instance of T itself, or an instance
of a subclass.
This creates the inspiration for a limited form of transitivity which isn't as
brain-bending as the full-fledged version in PyProtocols**. Specifically,
transitivity would be permitted only when no adaptation is involved in the
transitive part of the link. Adaptation would only be permitted on the final
non-transitive leg, where the result implements the target protocol.
I've got the skeleton of an implementation for that idea (using the
distributed adaptation approach and stealing liberally from the concepts in
PyProtocols) - I'll try to tidy that up to a postable form.
Cheers,
Nick.
** For those familiar with adapter chains in PyProtocols, the basic idea is to
permit only transitive links with a simplified length of 1, where every step
other than the last is a NO_ADAPTER_NEEDED step. The search algorithm in such
a simplified system can be a heck of a lot dumber than the one in PyProtocols
(since it only needs to keep track of visited nodes in order to avoid loops
and redundant searches, and the only error it has to detect is the presence of
more than 1 legal adaptation path), while still permitting the registration of
a protocol->protocol adapter that will work for any object that implements the
source protocol.
--
Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
---------------------------------------------------------------
http://www.boredomandlaziness.org
More information about the Python-3000
mailing list