[Types-sig] RE: PRE-PROPOSAL: Python Interfaces

Tim Peters tim_one@email.msn.com
Wed, 25 Nov 1998 01:12:47 -0500


[Uncle Timmy]
> ...
> IOW, Lists do *not* implement the Stack protocol just
> because "it looks like" they do -- if they do at all,
> it's only by virtue of List explicitly saying it implements
> specifically Stack.  Today, though, there's no way to draw
> the distinction at all.

[Gordo the Magnificent]
> Which brings up the point Paul made that if the all-omiscient
> Guido forgot to say that (the builtin) List implements Stack,
> and his time machine will have been in the body shop because
> of that fender-bender, then I'd better be able to say at
> runtime that "I know this is a List, but you'll treat it like
> a Stack anyway".

This all made more sense in the egroups context, where part of healing the
type/class split was widely taken to be erasing "needless" distinctions
between builtin and user-defined clypes (as good a name as any for a hybrid
class/type -- well, OK, really much worse than any other name I can think
of! so I'll stick with it).

In *that* world, you have three more choices:

1) If Guido only forgot to add Stack's push method to List, you can add your
own via subclassing:

clype Slack(List):
    __implements__ = Stack
    def push(self, thing): self.append(thing)

and pass a Slack to the Stack consumer.

2) Or add it to List directly if the Stack consumer isn't relying on
interfaces but on ad hoc hasattr tricks:

    List.push = lambda self, append: self.append(thing)

2) If Guido did implement all the Stack methods in List, and simply forgot
to anticipate the Stack interface, you could repair his failed precognition
yourself via e.g.

    List.__implements__.append(Stack)

No time machine required -- except maybe one that moves forward beyond
today's clypesplit.

>> OTOH, unlike e.g. JimF I have nothing against stuffing some
>> default implementation into interfaces.

> Yeah. Somehow my C++ "abstract base classes" always end up not
> being abstract.

I have more the Eiffel class model in mind, which makes no distinction at
all between classes and interfaces, behavior and specification, abstract and
concrete -- except in that the built-in doc tools generate different *views*
of a class depending on what you tell it to show you.  If you want an Eiffel
class that describes only interface, fine -- just "defer" all the methods.
If some methods can be implemented in terms of others, fine too -- supply
implementations for those methods and defer the rest.

The one thing Eiffel can do here Python can't (short of the more esoteric
stuff like automagically adjusted method pre/post-conditions and class
invariants) is say "ya, I know I inherited Stack, but I don't want *my* kids
to inherit Stack too unless they do it themselves".  Which addresses JimF's
biggest gripe with class inheritance.  I see the Scarecrow Proposal as
fixing that for Interfaces but leaving the problem untouched for Classes;
Eiffel solves both at the same time via a single mechanism.

>> [point 14 from Timmy's egroups manifesto]

> Which Basilica door did you nail this to? (IE, where can I
> read it?)

This stuff should really be moved to the Types SIG.  It's at

    http://www.egroups.com/list/python-classes/

although you probably need to go to the top page first and register for a
(free) account.

When you finally get to Python Classes, click the "by Date" button (the
thread view is useless), and start at the oldest.  Things get interesting
when the various "position papers" show up, and then get confused.
According to my Inbox, there are 40 msgs from that group I still haven't
made time to read.  But they probably solve everything <wink>.

> ...
> I will admit to being completely mystified by the following
> (from lib/module-select.html):
>
> "You may also define a wrapper class yourself, as long as it
>  has an appropriate fileno() method (that really returns a
>  Unix file descriptor, not just a random integer)."
>
> particularly-on-WIndows-ly y'rs

See?  Two months for now it can simply say:

    You may also define a wrapper class yourself, implementing
    the UNIXFileNo interface.

In this way we turn all confusions into Fred Drake's problem, who merely
needs to supply an insightful writeup for UNIXFileNo's index entry to point
at <0.7 wink>.

but-you'll-have-a-name-for-the-missing-info-
    as-well-as-a-natural-place-to-put-it-ly y'rs  - tim