[Python-Dev] PEP 246, redux

Phillip J. Eby pje at telecommunity.com
Wed Jan 12 22:50:52 CET 2005


At 09:30 PM 1/12/05 +0100, Alex Martelli wrote:

>On 2005 Jan 12, at 20:51, Phillip J. Eby wrote:
>    ...
>>There's a very simple reason.  If one is using only non-noisy adapters, 
>>there is absolutely no reason to ever define more than one adapter 
>>between the *same* two points.  If you do,
>
>...but there's no harm whatsoever done, either.  If I have four interfaces 
>I use regularly, A, B, C, D, and I have the need to adapt A->B, A->C, 
>B->D, C->D, with every one of these four adaptations being "the absolute 
>best way" (as you stated all interface adaptations must be), then why 
>should that be at all a problem?

It isn't a problem, but *only* if A is an interface.  If it's a concrete 
class, then A->B and A->C are not "perfect" adapters, so it *can* make a 
difference which one you pick, and you should be explicit.

However, implementing an algorithm to ignore only interface-to-interface 
ambiguity is more complex than just hollering whenever *any* ambiguity is 
found.  Also, people make mistakes and may have declared something they 
didn't mean to.  The cost to occasionally be a bit more explicit is IMO 
outweighed by the benefit of catching bugs that might otherwise go 
unnoticed, but produce an ambiguity as a side-effect of the buggy part.

It's *possible* that you'd still catch almost as many bugs if you ignored 
pure I-to-I diamonds, but I don't feel entirely comfortable about giving up 
that extra bit of protection, especially since it would make the checker 
*more* complex to try to *not* warn about that situation.

Also, in general I'm wary of introducing non-determinism into a system's 
behavior.  I consider keeping e.g. the first path declared or the last path 
declared to be a form of non-determinism because it makes the system 
sensitive to trivial things like the order of import statements.  The 
current algorithm alerts you to this non-determinism.

Perhaps it would be simplest for Python's interface system to issue a 
warning about ambiguities, but allow execution to proceed?


>(would it be LESS important to provide the error if everybody and their 
>cousin were interfacing and adapting with exhuberance...?)

Only in the use case where two people might legitimately create the same 
adapter, but neither of them can stop using their adapter in favor of the 
other person's, thus forcing them to work around the error.

Or, in the case where lots of people try to define adapter diamonds and 
don't want to go to the trouble of having their program behave 
deterministically.  :)


>1. if an interface adapter must ABSOLUTELY be perfect, transitivity is 
>fine, but the error makes no sense

The error only makes no sense if we assume that the human(s) really *mean* 
to be ambiguous.  Ambiguity suggests, however, that something *else* may be 
wrong.


>I suspect [2] holds.  But you're the one with experience, so if you stake 
>that on [1], and the "absolute best way" unconditional assertion, then, 
>fine, I guess, as per my previous message.  But the combination of 
>"absolute best way" _AND_ an error when somebody adds C->D is, in my 
>opinion, self-contradictory: experience or not, I can't support asserting 
>something and its contrary at the same time.

It's not contrary; it's a warning that "Are you sure you want to waste time 
writing another way to do the same thing when there's already a perfectly 
valid way to do it with a comparable number of adaptation steps 
involved?  Maybe your adapter is better-performing or less buggy in some 
way, but I'm just a machine so how would I know?  Please tell me which of 
these adapters is the *really* right one to use, thanks."  (Assuming that 
the machine is tactful enough to leave out mentioning that maybe you just 
made a mistake and declared the adapter between the wrong two points, you 
silly human you.)



>How can you claim that set of four adaptations is REDUNDANT, when adding a 
>FIFTH one (a direct A->D) would make it fine again per your rules?  This 
>is the first time I've heard an implied claim that redundancy is something 
>that can be eliminated by ADDING something, without taking anything away.

PyProtocols doesn't say the situation is redundant, it says it's 
*ambiguous*, which implies a *possible* redundancy.  I'm also saying that 
the ambiguity is nearly always (for me) an indicator of a *real* problem, 
not merely a not-so-explicit diamond.


>I don't NEED the chain, but I may well need each step; and by the premise 
>of "absolute best way" which you maintain, it must be innocuous if the 
>separate steps I need end up producing more than one chain -- what 
>difference can it make?!

Fair enough; however I think that in the event that the system must make 
such a choice, it must at *least* warn about non-deterministic 
behavior.  Even if you are claiming perfect adaptation, that doesn't 
necessarily mean you are correct in your claim!


>Each of the FOUR adapters coded can be absolutely perfect.  Thus, the 
>composite adapters which your beloved transitivity builds will also be 
>perfect, and it will be absolutely harmless to pick one of them at random.

Right, but the point of my examples was that in all but one extremely rare 
scenario, a *real*  ambiguity of this type is trivial to fix by being 
explicit.  *But*, it's more often the case that this ambiguity reflects an 
actual problem or error of some kind (at least IME to date), than that it 
indicates a harmless adapter diamond.  And when you attempt to make the 
path more explicit, you then discover what that other mistake was.  So, 
sometimes you are "wasting time" declaring that extra explicitness, and 
sometimes you save time because of it.  Whether this tradeoff is right for 
everybody, I can't say; it's a little bit like static typing, but OTOH ISTM 
that it comes up much less often than static typing errors do, and it only 
has to be fixed once for each diamond.  (i.e., it doesn't propagate into 
every possible aspect of your program.)



More information about the Python-Dev mailing list