[Python-3000] iostack and Oh Oh (original) (raw)
Phillip J. Eby pje at telecommunity.com
Wed Dec 6 22:45:14 CET 2006
- Previous message: [Python-3000] iostack and Oh Oh
- Next message: [Python-3000] iostack and Oh Oh
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
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.
class Mapping(Interface):
"""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 or set).
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 examples.
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 problem.
- Previous message: [Python-3000] iostack and Oh Oh
- Next message: [Python-3000] iostack and Oh Oh
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]