PEP 245

Alex Martelli aleaxit at yahoo.com
Thu Apr 5 03:28:46 EDT 2001


"Clark C. Evans" <cce at clarkevans.com> wrote in message
news:mailman.986444107.28413.python-list at python.org...
> > It is clear to me that either I am the only one who things
> > that interfaces, at least in the proposed form, are next to
> > useless in Python, or those who agree with me do not read the
> > news group, or simply don't care enough to reply.
>
> Some mechanism is needed to identify an object as
> an implementer of a particular protocol, searching
> for the existance of "getitem" and the like seems
> like very poor practice.

It may be better than nothing in some cases (I call
it the "Accurate-Checking Look-before-you-leap" idiom,
and have a recipe on it submitted to the Python
Cookbook, but I still need to edit it to the Cookbook
editor's satisfaction), so defining it away as "very
poor practice" may be quite misleading _given the
current state of Python_.  But I fully agree that
PEPs 245 and 246 would represent improvements!


> > Indeed, interfaces in a loosely typed language that
> > supports introspection -- that's a real joke!
>
> What is important isn't the function names,

...nor just their _signatures_ either, in as
much as Python supports them (number and names
of arguments)...

> but rather the "intent" of the programmer
> who asserts that his/her class complies with
> a given set of expectations.

Bingo!  A "contract" -- including some promises
on the existence and signature of methods, some
on functionality (pre/post conditions), even,
maybe, some on performance.  Austern's "Generic
Programming and the STL" focuses on "a set of
abstract _concepts_ ... a type conforms to one
of those concepts if it satisfies a certain set
of requirements ... this hierarchy of concepts is
the conceptual structure ... the most important
part ... what makes reuse and interoperability
possible ... the essence of generic programming".

Focusing on the amount of compile-time, or even
run-time, _checking_, that a certain language can
offer, is missing the point -- _expressiveness_
is what we need to ask, so the "abstract concepts"
can be *stated* formally.  Some subset of them
(maybe, depending on language, the empty set:-)
will be compile-time checkable, some (ditto) only
run-time checkable -- and many important concepts
will not be checkable at all: Turing's results on
the "Halting Problem" ensure this, so it's not
something that a particular language can solve.

No problem!  Letting the programmer express his
or her _design intent_ clearly in the language
will be a big help anyway.  The very least we can
ask is being able to _state_ "this thingy, here,
conforms to the 'ReadableForwardOnlyStream' abstract
concept" (call it protocol, interface, concept --
the choice of name is a secondary issue); even
better, by PEP 246, being able to ask for some
'adaptation' of object-to-concept if feasible.

Whatever subset of the concept can be expressed
in the language will further help, and a further
small help may come if some checking can also be
automatically performed (the earlier the better),
but *all of this is secondary* -- the *primary*
need is for direct support of the primitive
notion of 'protocol' (aka 'interface', etc, etc),
as (e.g.) per PEP 245, and the most useful single
step beyond that is the notion of adaptation (as
per PEP 246).


> There currently
> isn't a standard way to express this in Python.
> I think PEP 245 is a good approach.
>
> I think most people agree that Python has
> a "hole" here that needs to be plugged.  If

Not a _gaping_ hole, but, yes, a lack of some
importance.

> you don't like the current proposal, perhaps
> you should suggest an alternative which
> provides the required differentiation?
>
> Either that or make a convincing argument
> why searching for function names is indeed
> acceptable.  I think it breaks down quickly.

It stretches up to some point, but not much
further.  For example: two very basic protocols
in current Python are 'sequence' and 'mapping';
they've been around for quite some time, and
are even documented as such (not with the full
clarity that protocols formally defined in the
language would enable, of course, but still).

Checking whether a given object IS 'a sequence'
or 'a mapping' is, however, a problem!  Being
able to "get an item" by indexing does not
distinguish between the two concepts; a given
mapping may happen to allow "obj[0]", because
0 might be a current key in the mapping; having
a length characterizes a sequence, but sequences
_without_ a length can still be very useful
(e.g., in a for-loop, or a zip call, ...)...

Formalizing even just these simple hierarchies
of abstract concepts would be much more effective
than the current situation.  Checking for the
existence of functions with certain names and
signatures doesn't go far enough, by a lot...

> For instance __iter__ has to return self
> in the iterator proposal to know that
> a class is an iterator (having the method
> "next()" is not sufficient).  This kind
> of ad-hock interface negotiotation kinda
> hurts interoperability, no?

It does make for a lot of work and a still
unsatisfactory situation.  Besides, if it is
recognized that 'matching a protocol'/'being
adapted to it' is an important idea, it
makes no sense for every programmer to have
to re-invent his or her own introspective
means to check it to some degree of effort
and accuracy... and still be left with no
way to _assert_ 'this thingy satisfies this
protocol' precisely ('this protocol' is never
clearly identified, even for crucial things
that have been around a long time such as
sequences and "file-like-objects", when such
compliance-assertions are left to comments
and docstrings!-).


Alex






More information about the Python-list mailing list