[Python-3000] iostack and Oh Oh
Phillip J. Eby
pje at telecommunity.com
Wed Dec 6 22:45:14 CET 2006
At 02:58 PM 12/6/2006 -0600, Guido van Rossum wrote:
>On 12/5/06, Phillip J. Eby <pje at telecommunity.com> wrote:
> > At 09:59 AM 12/5/2006 -0600, Guido van Rossum wrote:
> > >My point is that an interface can *document* (at least in English) a
> > >"contract" about the invariants between operations. While I'm not into
> > >enforcing or verifying such contracts, I'm very interested in
> > >documenting them. For example, something that has "mapping" behavior
> > >has a very different relationship between x[y] and "y in x" than
> > >something that has "sequence" behavior.
> > If you're using the interface solely
> > for documentation, then a namespace-oriented interface suffices to
> provide it.
>I don't follow. I feel awfully stupid right now -- I have a major
>roadblock to understanding how your proposal helps my use case and you
>think that it doesn't even need answering.
I was just saying that if you want interfaces for documentation, then a
docstring on the class implementing the namespace should do the trick. I.e.
"""Document some invariants in this string"""
Is there something else you wanted it to do besides *hold* the documentation?
>Anyway I don't think it is right to claim that there are many
>different operations if the normal way of spelling them is overloaded.
>I see these overloaded operations as *the same* operation (a GF as you
>say) but with different semantics (and sometimes a different return
>type) based on what category of object it is (e.g. mapping, sequence
If there isn't any other way to distinguish the operations, then I'd
suggest having an 'ismapping' or 'issequence' operation whose sole purpose
is to separate one from the other. This has the nice side effect of being
able to use those operations for interface inspection, in the case where
you decide to do this (despite it being seriously unwise, due to
conflicting meanings in context).
>The "mapping" example you claim caused so much trouble due to
>different understanding of what it means to be a mapping can IMO be
>addressed quite well by adopting a hierarchy of mapping ABCs as
>sketched in Bill J's wiki page. A lot of the problems in the example
>(and probably in Zope's interfaces) are caused by the non-existence of
>a *standard* set of ABCs that people can use to model their classes.
This happens even with interfaces (or special attributes in the Zope 2
case) that were *Zope-defined*. The stdlib examples are just that -- more
The thing that motivated me to ditch zope.interface and write PyProtocols
in the first place was the realization that interface inspection was
causing the same class of problems that attribute inspection did. And it
didn't matter if the interfaces were defined by the stdlib, Zope, or PEAK,
it was producing the same kind of "function A does this with IFoo, but
function B does this other thing with IFoo, and I only want function A to
do that" problems.
In other words, it's the *if-then* itself that causes the problems. It
doesn't much matter *what* the if-then tests for.
What I realized then, however, was that with adaptation, A and B can both
define an IFooA and IFooB, and define default adapters for IFoo. Then, if
there's a conflict for a new type T, you can define an adapter from
T->IFooA and/or T->IFooB and get what you want without any problems. The
if-then's go away, and all is well.
Of course, creating all those interfaces is a pain, but it works. Later I
realized that generic functions do the same thing without needing any new
interfaces; you just define overloads for A and B, or A and B just factor
out their type-testing into a new GF.
I would also like to point out again, though, that the mechanism I've
proposed (wrapping generic functions to create interfaces) actually
supports (or can be made to support, using appropriate convenience
functions) all the use cases that have been put forth for interfaces,
adaptation, and generic functions. At least, the use cases I understand.
To support interface inspection in the "mapping vs. sequence", my proposed
approach requires that you define a query operation like ismapping() or
issequence(). This is indeed more work. My argument, however, is that
this is a *good* thing, because interface inspection in the general case is
*evil*: it leads to the unfixable contextual interpretations problem,
whenever two developers write code that inspects the same interface for
different purposes. So, I think it's perfectly acceptable to make people
jump through an extra hoop in order to do that sort of thing, especially
since it's rare that you're going to have a mapping vs. sequence type of
More information about the Python-3000