[Python-Dev] Son of PEP 246, redux

Phillip J. Eby pje at telecommunity.com
Thu Jan 13 15:32:49 CET 2005


At 08:50 AM 1/13/05 +0100, Alex Martelli wrote:
>Your proposals are novel and interesting.  They also go WAY deeper into a 
>critical reappraisal of the whole object model of Python, which has always 
>been quite reasonably close to the above-mentioned "canon" and indeed has 
>been getting _more_ so, rather than less, since 2.2 (albeit in a uniquely 
>Pythonical way, as is Python's wont -- but not conceptually, nor, mostly, 
>practically, all that VERY far from canonic OOP).

Actually, the whole generic function thing was just a way to break out of 
the typing problems the Python community has struggled with for 
years.  Every attempt to bring typing or interfaces to Python has run 
aground on simple, practical concepts like, "what is the abstract type of 
dict?  file?"

In essence, the answer is that Python's object model *already* has a 
concept of type...  duck typing!  Basically, I'm proposing a way to 
"formalize" duck typing...  when you say you want a 'file', then when you 
call the object's read method, it "reads like a file".

This isn't a critical reappraisal of Python's current object model at 
all!  It's a reappraisal of the ways we've been trying (and largely 
failing) to make it fit into the mold of other languages' object models.


>  Moreover, your proposals are at a very early stage and no doubt need a 
> lot more experience, discussion, maturation, and give-and-take.

Agreed.  In particular, operations on numeric types are the main area that 
needs conceptual work; most of the rest is implementation details.  I hope 
to spend some time prototyping an implementation this weekend (I start a 
new contract today, so I'll be busy with "real work" till then).

Nonetheless, the idea is so exciting I could barely sleep, and even as I 
woke this morning my head was spinning with comparisons of adaptation 
networks and operation networks, finding them isomorphic no matter what I 
tried.

One really exciting part is that this concept basically allows you to write 
"good" adapters, while making it very difficult or impossible to write 
"bad" ones!  Since it forces adapters to have no per-adapter state, it 
almost literally forces you to only create "as-a" adapters.  For example, 
if you try to define file operations on a string, you're dead in the water 
before you even start: strings have no place to *store* any state.  So, you 
can't adapt an immutable into a mutable.  You *can*, however, add extra 
state to a mutable, but it has to be per-object state, not per-adapter 
state.  (Coincidentally, this eliminates the need for PyProtocols' somewhat 
kludgy concept of "sticky" adapters.)

As a result of this, this adapter model is shaped like a superset of COM - 
you can adapt an object as many times as you like, and the adapters you get 
are basically "pointers to interfaces" on the same object, with no adapter 
composition.  And adapt(x,object) can always give you back the "original" 
object.

This model also has some potential to improve performance: adapter classes 
have all their methods in one dictionary, so there's no __mro__ scan, and 
they have no instance dictionary, so there's no __dict__ lookup.  This 
should mean faster lookups of methods that would otherwise be inherited, 
even without any special interpreter support.  And it also allows a 
possible fast-path opcode to be used for calling methods on a type-declared 
parameter or variable, possibly eventually streamlined to a vtable-like 
structure eliminating any dictionary lookups at all (except at function 
definition time, to bind names in the code object to vtable offsets 
obtained from the types being bound to the function signature).  But of 
course all that is much further down the road.

Anyway, I suppose the *really* exciting thing about all this is how *many* 
different problems the approach seems to address.  :)

(Like automatically detecting certain classes of Liskov violations, for 
example.  And not having to create adapter classes by hand.  And being able 
to support Ping's abstract operations.  Etc., etc., etc.)


>So, I think the best course of action at this time might be for me to edit 
>PEP 246 to reflect some of this enormously voluminous discussion, 
>including points of contention (it's part of a PEP's job to also indicate 
>points of dissent, after all); and I think you should get a new PEP number 
>to use for your new ideas, and develop them on that separate PEP, say PEP 
>XYZ.  Knowing that a rethink of the whole object-model and related canon 
>is going on at the same time should help me keep PEP 246 reasonably 
>minimal and spare, very much in the spirit of YAGNI -- as few features as 
>possible, for now.

Sounds good to me.


>If Guido, in consequence, decides to completely block 246's progress while 
>waiting for the Copernican Revolution of your new PEP XYZ to mature, so be 
>it -- his ``nose'' will no doubt be the best guide to him on the matter.

It's not that big of a revolution, really.  This should make Python *more* 
like Python, not less.


>   But I hope that, in the same pragmatic and minimalist spirit as his 
> "stop the flames" Artima post -- proposing minimalistic interfaces and 
> adaptation syntax as a starting point, while yet keeping as a background 
> reflection the rich and complicated possibilities of parameterized types 
> &c as discussed in his previous Artima entries -- he'll still give a 
> minimalistic PEP 246 the go-ahead so that widespread, real-world 
> experimentation with adaptation and his other proposals can proceed, and 
> give many Pythonistas some practical experience which will make future 
> discussions and developments much sounder-based and productive.

Well, as a practical matter, every current interface package for Python 
already implements the "old" PEP 246, so nothing stops people from 
experimenting with it now, any more than in the past.

But, since I think that my approach can simply be implemented as a more 
sophisticated version of PEP 246's new global adapter registry, there is no 
real reason for the PEPs to actually *conflict*.  The only area of 
potential conflict is that I think __conform__ and __adapt__ might be able 
to wither away completely in the presence of a suitably powerful registry.


>So, what do you think -- does this new plan of action sound reasonable to you?

Yes.  I'll prototype and PEP, unless somebody else gets as excited as I am 
and does it first.  ;)  I'll probably call it "Duck Typing and Adaptation" 
or some such.



More information about the Python-Dev mailing list