[Python-3000] Adaptation: T->P vs P->P

Tim Hochberg tim.hochberg at cox.net
Mon Apr 3 19:47:47 CEST 2006


Michael Chermside wrote:

>Tim Hochberg writes:
>  
>
>>In this thread, Alex has been advocating adaption where types are
>>adapted to protocols: T->P adaption for short. By contrast, my two
>>sample implementations have involved Protocol->Protocol adaption
>>[...] P->P adaption for short.
>>    
>>
>
>  
>
>>However, there is a huge difference in scale here. A class will
>>typically only satisfy a few protocols, whereas it could potentially be
>>associated with many adapters. Similarly an adapter will typically be
>>associated with only a single source protocol, but it may be associated
>>with many, many types. Just to make this concrete, I imagine there will
>>be many adapters that work on every sequence type
>>    
>>
>
>I may be misinterpreting what Tim is saying here, but it sounds like
>this touches on the idea of *transitivity* in adaptation.
>

Your are mispresenting what I'm *trying* to say. That may well be my fault.

> That is, Tim
>is proposing that there are a small number of "protocols", but I can't
>tell the difference between a protocol and an adaption target so I am
>taking them to be synonomous. I am (and have been for nearly 2 years...
>Alex: your previous efforts at evangalism have not been *totally* useless)
>a fan of adaption. But I am *deeply* concerned about introducing
>transitive adaption where it is assumed that registering ((A B) f) and
>((B C) g) implies ((A C) lambda x: f(g(x))
>
>I have heard it argued previously (I apologize, but I forget who said this)
>that if f *really* adapts A to B and g *really* adapts B to C, then their
>composition must really adapt A to C, and I understand the mathematical
>inevitability behind this statement. But I fear that in the real world
>there are often subtle distinctions and corner cases that are ignored
>for the sake of practicality which make such transitive adaption dangerous.
>After all, a substantial portion of Python classes fail true to achieve
>true Liskov substitutability despite this being a widely-understood
>concept.
>  
>
I'm completely in agreement with that actually.

>Okay... time for me to stop attacking a position (pro transitivity) that
>no one has explicitly taken in this discussion and return to what Tim was
>saying. He claims:
>  
>
>>let's define A=>B to
>>mean "A needs to know about B". For T->P adaption:
>>    T=>A or A=>T or P=>(A and T) or U=>(A and T and P)
>>For P->P adaption:
>>    T=>Psrc or P=>Psrc or U=>Psrc
>>  Generally A can be assumed to know about Psrc, so I've left that out.
>>    
>>
>
>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')

>This is a tempting
>game... it avoids having to have even a third party know about both the
>type and the protocol to be satisfied. But I would rather FORCE someone
>(even a third party) to at least glance at the specific case and
>reassure us that it works. If the individual wants to do a quick and
>sloppy job rather than a careful one, then it is reduced to a question
>of whose libraries I trust, which I a problem I understand how to handle.
>  
>
The difference in T->P and P->P is that in the first the third party 
needs to know about every type they want to adapt, while in the second 
the third party needs to know about every protocol that they want to 
adapt. The second should generally be a much smaller burden. It's true 
that you could get into trouble if someone lies about conformance to a 
protocol. If a class is associated with a protocol it doesn't really 
satisfy or an adapter relies on some information outside the protocol, 
then this will break. That's a general problem though and probably not 
made appreciably worse by P->P adaption versus T->P adaption.

Note that T-P adaption is really a subset of P->P adaption as long as 
you let types be used as protocols.

>To return to the example that we used previously in this thread, it seems
>that creating an __index__ special method would not be necessary if
>adaption were in place... we could instead ask classes to register an
>adapter to the "python.as_index" protocol. But if we were to infer that
>anything satisfying "python.as_int" necessarily satisfied "python.as_index",
>then we would have defeated the purpose of the feature.
>
>One last point: it is entirely possible that I have misunderstood
>completely. If so, please gently explain why.
>  
>
I've tried. Now whether that explanation is comprehensible or not is 
another matter.

Regards,

-tim




More information about the Python-3000 mailing list