[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