[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