Oh come on, PJE, let's have some fun and shake up the establishment. :-)
When you're working with some arbitrary object, you don't want to know anything about its implementation. Using methods instead of attributes isolates knowledge of data structures, but you still have to know what interfaces the object supports. Adaptation lets you abstract away even the knowledge of an object's interfaces.
The important consideration is how often you work with arbitrary objects, as opposed to objects under your direct control. In Zope, it turns out that you end up working with arbitrary objects very frequently. In Zope 3, most code is going to be completely agnostic of the actual interfaces objects support.
Just as in days past we programmers made the transition from working directly with data structures to calling methods, maybe in the future, we'll transition to using adapters instead of calling methods. And it could be that programmers will flock to the first language that makes adaptation easier than any other language.
Here is a syntax I've been toying with:
This is equivalent to "adapt(foo, IWrite).write(bar)", but hopefully it more clearly expresses that you can think of "write" as a method of nearly any object.
The double colon is nearly borrowed from C++ and XPath, but a lot of Python programmers don't know that stuff. Some other possibilities:
(foo as IWrite).write(bar)
Ok, after writing them out, I think the last suggestion is by far the most readable. It requires parentheses, but that could actually be a benefit, since it's the only suggestion that lets you store the adapted object in a variable:
baz = foo as IWrite
The "as" keyword could be implemented through an __adapt__ magic name.
I should write about this on comp.lang.python and see how well it floats. :-)