[Python-Dev] type categories

Samuele Pedroni Samuele Pedroni" <pedroni@inf.ethz.ch
Fri, 23 Aug 2002 23:00:10 +0200


some thoughts of mine

[GvR]
> Agreeing on an ontology seems the hardest part to me.

Why does it seem such a daunting task?

i) much of python code depends concretely on interfaces with the granularity
from one to a bunch of methods, especially code expecting base-type-like
implementations.
ii) people appreciate to be able to implement just the minimal subset of
methods that makes things work

[Obviously here I'm not talking about large frameworks like Zope]

We are not in vacuum. There is Python code out there, and progammers with ideas
about what is like programming in Python.

[Maybe I just restate the obvious and repeat myself but it seems that for some
people not only type checking but in general explicitness about types is a tabu
for Python code.
OTOH there _exists_ Python code that  as input depends/requires subclasses of
some _specific_ abstract classes. And even Smalltalk has - when "reasonable"
and "necessary" - a kind of interface notion, in the form of isFoo method
defined on Object and overridden to return "yes sir" down the hierarchy]

It seems to me that there is no route to the advantages of type categories
without some explicitness.

Now to the point.
[Here my target is more dispatching and "distinguishing" by type categories
than type checking, PEP 246 issue is far from orthogonal but here I will ignore
it because I don't want my head to explode <wink>]

Maybe it is obvious but anyway type categories' "problem" should be framed wrt:
- what kind of coding style we want to enable (or maybe respectively
deprecate)?
- what problems are we solving?
- what kind of code will not work anymore?
- what "migration path" for such code, or to the new style?

Let's consider an exemplar fragment:

if hasattr(f,'write'):
 ... # needs just f.write
else: # f is not file-like
 ...

possible future styles:

1)

if doesimplement(f,FileLike):
 ...
else:
 ...

problems: the "exponential" ontology problem, or the problem, if we limit
ourselves only to large granularity interfaces and we interpret them
strictly[*], that the programmer must implement more methods than strictly
necessary.

[*] the point is whether an interface should be interpreted as "all the
signatures implemented" . Here is not relevant this is checked or enforced at
class definition time.

2)

if doesimplement(f,Category('write')):
 ...
else:
 ...

if we allow for such on-the-fly constructed interfaces (I hope one can
extrapolate what I mean with that) we maybe solve the "exponential" ontology
problem, but this code is not really an improvement over the code using
hasattr; what we are interested in is not whether f has some kind of write
method but whether f has a file-like write method. Through interfaces one wants
to check and convey commitment more than at the signature level.

Can we do better?

It would be nice to find some kind of middle-ground between hasattr(.,'write')
and large granularity strict interfaces (LGSI).

My humble ideas: these are just two points picked in that entire range
(hasattr - LSGI), other variations are maybe useful, necessary, or reasonable.

a) As a "workaround" it should be possible to declare that a class implements
an interface partially, that means some subset of it.
Then it is an open issue whether there should be ways to check both for strict
and non-strict implementation, or some general control to tweak all checkings
and/or enable warnings. [Do Zope interfaces already allow for this?]

b) OK with a) but if I want potentially to be strict and still deal with:

"b) much of python code concretely depends on interfaces with the granularity
from one to a bunch of methods"

we should let people be precise about what subset of an interface they are
implementing, like

- I'm implemeting a subset of FileLike so consider the corresponding matching
signatures
- or, with finer control, I'm implementing FileLike 'write' and - no  - my
'tell' has nothing to do with file-like
...

and more importantly it should be possible to check for such subsets:

if doesimplement(f,PartCategory(FileLike,['write'])):
   # Yup, I know, this is ugly and begs for sugar
 ...
else:
 ...

[And mildly interestingly such code can degrade to just check for
hasattr(.,'write') for "migration" and possibly emit warnings]

regards, Samuele Pedroni.

PS: I know, here I have not dealt with implementation or performance problems
and the killing details.