[Python-Dev] Son of PEP 246, redux

Clark C. Evans cce at clarkevans.com
Thu Jan 13 05:26:06 CET 2005


Phillip,

In my mind, the driving use-case for PEP 246 was to allow causual
programmers to plug components together and have it 'just work'; it
does this by enabling the component vendors to carry on a discussion
via __adapt__ and __conform__ to work together.  I was not picturing
that your average developer would be using this sort of thing.

On Wed, Jan 12, 2005 at 09:57:07PM -0500, Phillip J. Eby wrote:
| First, adapter abuse is *extremely* attractive to someone new to the 
| concept -- so from here on out I'm going to forget about the idea that we 
| can teach people to avoid this solely by telling them "the right way to 
| do it" up front.
| 
| The second, much subtler point I noticed from your posts, was that 
| *adapter abuse tends to sooner or later result in adapter diamonds*.

However, I'd like to assert that these cases emerge when you have a
registry /w automatic transitive adaptation.  These problems can be
avoided quite easily by:

   - not doing transitive adaptation automatically

   - making it an error to register more than one adapter from 
     A to Z at any given time; in effect, ban diamonds from ever
     being created

   - make it easy for a user to construct and register an adapter
     from A to Z, via an intermediate X,

        adapt.registerTransitive(A,X,Z)
     
   - if an adaptation from A to Z isn't possible, give a very
     meaningful error listing the possible pathways that one
     could build a 'transitive adaption', adaptation path', 
     perhaps even showing the command that will do it:

         adapt.registerTransitive(A,B,C,Z)
         adapt.registerTranstive(A,Q,Z)
         adapt.registerTranstive(A,X,Z)

The results of this operation:

   - most component vendors will use __adapt__ and __conform__
     rather than use the 'higher-precedent' registry; therefore,
     transitive adaption isn't that common to start with

   - if two libraries register incompatible adpater chains
     during the 'import' of the module, then it will be an
     error that the casual developer will associate with 
     the module, and not with their code
     
   - casual users are given a nice message, like

      "Cannot automatically convert a String to a File. 
     
       Perhaps you should do a manual conversion of your String
       to a File.  Alternatively, there happen to be two adaptation
       paths which could do this for you, but you have to explicitly
       enable the pathway which matches your intent:
       
       To convert a String to a File via StringIO, call:
       adapt.registerTranstive(String,StringIO,File)

       To convert a String to a File via FileName, call:
       adapt.registerTranstive(String,FileName,File)"

| What that suggests to me is that it might well be safe enough in practice 
| to let new users of adaptation whack their hand with the mallet now and 
| then, given that *now* it's possible to give a much better explanation of 
| "as a" than it was before.

By disabling (the quite dangerous?) transitive adaptation, one could
guide the user along to the result they require without having them
shoot themselves in the foot first.

| What this also suggests to me is that maybe adaptation and interfaces are 
| the wrong solution to the problems we've been trying to solve with them 
| -- adding more objects to solve the problems created by having lots of 
| objects.  :)

I didn't see how your remaining post, in particular, Dylan's protocol was 
much different from an mixin/abstract-base-class. Regardless,
getting back to the main goal I had when writing PEP 246 -- your
alternative proposal still doesn't seem to provide a mechanism for
component developers to have a dialogue with one another to connect
components without involving the application programmer. 

Cheers!

Clark


More information about the Python-Dev mailing list