[Python-3000] Abilities / Interfaces

Phillip J. Eby pje at telecommunity.com
Thu Nov 23 01:20:22 CET 2006


At 03:30 PM 11/22/2006 -0800, Guido van Rossum wrote:
>Oh, it would all be so much easier if we could all be in the same room
>for a day...

Well, there's always Skype/Gtalk et al...  :)

>The problem often seems to be that I don't have the imagination to
>come up with a suitable implementation for the abstraction you are
>describing, and at that point it's no longer an abstraction but an
>arbitrary string of words to me.

This, and the rest of your message helps a lot, at least in terms of me 
getting past the "what the heck does he *want* from me?" question.  :)


>I criticize the implementation in order to understand the abstraction
>better.  Since the implementation is often the only clue I have for
>understanding the abstraction, if the implementation oversimplifies
>things or has an obvious hole in it this distracts from the
>understanding.

Ah.  Here, I usually resist working out all the details of a 
production-quality implementation, because then it seems to make it harder 
to talk about the *ideas* and select a *good* implementation approach.  But 
I will do my best to accommodate this now that I understand more 
specifically what you need.


>I don't know. In general, I find implementations that draw too
>strongly on PEAK or RuleDispatch distracting because I'm not familiar
>with their semantics or terminology and I'm in the "self getattr x y"
>situation again.

Fair enough, except that I haven't drawn on them as much as you think I 
have; in this discussion I've only referred to the 'simplegeneric' and 
'DecoratorTools' libraries, both of which have usage examples on their 
CheeseShop pages, and both of which are only a few hundred lines of code 
(~100 for simplegeneric, ~350 for all of DecoratorTools including many 
things besides the comparatively brief decorate_class feature).

What has happened instead, is that when I have introduced hypothetical 
constructs like 'addmethod', you've assumed that I was referring to 
something that existed elsewhere and were then saying "but I don't know 
what that is".  But I was saying, "here is a thing I'm *proposing*, and 
here is how it would work".


>But I think I could use some help with hasmethod. Suppose I
>wanted to write the sendmail example using hasmethod. (I know it can
>be written differently, but other examples may need hasmethod, and I'm
>familiar with the sendmail example.) Could you should (a) what the
>example would look like and

Assuming the existence of an 'as_string()' generic function, either 
built-in or in the stdlib, one could write it as:

     if hasmethod(as_string, to_addrs):
         # it's a string-like thing
         to_addrs = [to_addrs]

The assumption here is that we've chosen to have an 'as_string' generic to 
denote a general notion of "stringness".  The semantics of 'as_string' is 
that it returns a string of the same "value" as its input, or raises an 
error if its input isn't "really" a string.

In other words, this function would be to strings what __index__ is to 
integers, if that makes sense.  It doesn't convert non-strings to strings, 
it only converts conceptual strings to concrete strings, the way __index__ 
converts conceptual integers to concrete integers.  (Assuming I understand 
__index__ correctly, of course, because I tuned out after some of the 
earliest discussions about what it should do.)

So, the generic function 'as_string' here functions as an "interface" or 
"ability".  Of course, instead of being called 'as_string', it could live 
as an attribute of the 'str' type, e.g. 'str.cast':

     if hasmethod(str.cast, to_addrs):
         # it's a string-like thing
         to_addrs = [to_addrs]

I make the assumption, by the way, that once the string-like thing is 
passed to something that really needs a concrete, C-compatible string (like 
open() or socket.send()), that it will actually *call* 'str.cast' to get 
that string.


>(b) what would / could go on behind the
>scenes to make it work?

The generic function's __hasmethod__ checks for an implementation.  This 
can happen via __special__ attribute check (for built-in generics like 
len/iter/etc.) or via registry lookup (other kinds of generics).


>Bonus points for an attempt to show that it
>can be implemented efficiently.

Registry lookup is a dict lookup against MRO -- i.e., it's like an 
attribute access check.  Slot checks are O(1) if there's a C-level slot, or 
equivalent to an attribute access check otherwise.



More information about the Python-3000 mailing list