[Python-Dev] PEP 246, redux
Phillip J. Eby
pje at telecommunity.com
Wed Jan 12 21:42:32 CET 2005
At 08:59 PM 1/12/05 +0100, Alex Martelli wrote:
>Even though Guido claimed I have been belaboring the following point, I do
>think it's crucial and I still haven't seen you answer it.
My post on that probably crossed with this post of yours; it contains an
excruciating analysis of why I chose to consider such paths
dubious. However, I'll briefly answer your specific questions
here. (Well, briefly for ME! ;) )
> If *any* I1->I2 adapter, by the very fact of its existence, asserts
> it's the *absolute best way* to adapt ANY implementation of I1 into I2;
> then why should the existence of two equal-length shortest paths
> A->I1->I2 and A->I3->I2 be considered a problem in any sense? Pick
> either, at random or by whatever rule: you trust that they're BOTH the
> absolute best, so they must be absolutely identical anyway.
Because if you have asserted that it is the absolute best, why did you
write *another* one that's equally good? This suggests that at least one
of the paths you ended up with was unintentional: created, for example, via
inappropriate use of interface inheritance.
Anyway, the other post has a detailed analysis for all the circumstances I
can think of where you *might* have such a set of ambiguous adapter paths,
and why it's excruciatingly rare that you would not in fact care when such
a situation existed, and why the error is therefore valuable in pointing
out the (almost certainly unintended) duplication.
>If you agree that this is the only sensible behavior, and PyProtocols'
>current behavior (TypeError for two paths of equal length save in a few
>special cases), then I guess can accept your stance that providing
>adaptation between interfaces implies the strongest possible degree of
>commitment to perfection, and that this new conception of *absolute best
>way* entirely and totally replaces previous weaker and more sensible
>descriptions, such as for example in
><http://peak.telecommunity.com/protocol_ref/proto-implication.html> that
>shorter chains "are less likely to be a ``lossy'' conversion".
>``less likely'' and ``absolute best way'' just can't coexist. Two
>"absolute best ways" to do the same thing are exactly equally likely to be
>``lossy'': that likelihood is ZERO, if "absolute" means anything.
First off, as a result of our conversations here, I'm aware that the
PyProtocols documentation needs updating; it was based on some of my
*earliest* thinking about adaptation, before I realized how critical the
distinction between class-to-interface and interface-to-interface
adaptation really was. And, my later thinking has only really been
properly explained (even to my satisfaction!) during this
discussion. Indeed, there are lots of things I know now about when to
adapt and when not to, that I had only the faintest idea of when I
originally wrote the documentation.
Second, if the error PyProtocols produces became a problem in practice, it
could potentially be downgraded to a warning, or even disabled
entirely. However, my experience with it has been that the *real* reason
to flag adapter ambiguities is that they usually reveal some *other*
problem, that would be much harder to find otherwise.
>((Preferring shorter chains as a heuristic for faster ones may be very
>reasonable approach if performance is a secondary consideration, as I've
>already mentioned; if performance were more important than that, then
>other ``costs'' besides the extreme NO_ADAPTER_NEEDED [[0 cost]] and
>DOES_NOT_SUPPORT [[infinite cost]] should be accepted, and the
>minimal-cost path ensured -- I do not think any such complication is
>warranted)).
Actually, the nature of the transitive algorithm PyProtocols uses is that
it must track these running costs and pass them around anyway, so it is
always possible to call one of its primitive APIs to force a certain cost
consideration. However, I have never actually had to use it, and I
discourage others from playing with it, because I think the need to use it
would be highly indicative of some other problem, like inappropriate use of
adaptation or at least of I-to-I relationships.
>If you agree that it cannot be an error to have two separate paths of
>"absolute best ways" (thus equally perfect) of equal length, then I can
>accept your stance that one must ensure the "absolute best way" each time
>one codes and registers an I -> I adapter (and each time one interface
>inherits another interface, apparently); I can then do half the rewrite of
>the PEP 246 draft (the changes already mentioned and roughly agreed) and
>turn it over to you as new first author to complete with the transitivity
>details &c.
>
>If there is any doubt whatsoever marring that perfection, that "absolute
>best way", then I fear we're back at square one.
The only doubt is that somebody may have *erroneously* created a duplicate
adapter, or an unintended duplicate path via a NO_ADAPTER_NEEDED link (e.g.
by declaring that a class implements an interface directly, or interface
inheritance). Thus, even though such an adapter is technically correct and
acceptable, it is only so if that's what you really *meant* to do.
But, if the adapters are *really* perfect, then by definition you are
wasting your time defining "more than one way to do it", so it probably
means you are making *some* kind of mistake, even if it's only the mistake
of duplicating effort needlessly! More likely, however, it means you have
made some other mistake, like inappropriate interface inheritance.
At least 9 times out of 10, when I receive an ambiguous adapter path error,
it's because I just added some kind of NO_ADAPTER_NEEDED link: either
class-implements-interface, or interface-subclasses-interface, and I did so
without having thought about the consequences of having that path. The
error tells me, "hey, you need to think about what you're doing here and be
more explicit about what is going on, because there are some broader
implications to what you just did."
It's not always immediately obvious how to fix it, but it's almost always
obvious that I actually *have* done something wrong, as soon as I think
about it; it's not just a spurious error.
Anyway, hopefully this post and the other one will be convincing that
considering ambiguity to be an error *reinforces* the idea of I-to-I
perfection, rather than undermining it. (After all, if you've written a
perfect one, and there's already one there, then either one of you is
mistaken, or you are wasting your time writing one!)
More information about the Python-Dev
mailing list