typetesting, adaptation, typeclasses, ... (was Re: isinstance() considered harmful)

Alex Martelli aleax at aleax.it
Fri Jan 25 05:32:24 EST 2002


"Jason Orendorff" <jason at jorendorff.com> wrote in message
news:mailman.1011932318.3830.python-list at python.org...
> Alex Martelli wrote:
> > You don't need EVERY method -- you only need the methods you need.  If
> > you never call x.extend, for example, why put x's author to the useless
> > burden of implementing extend?
>
> -1
>
> This makes your function less of an abstraction.  The caller
> now needs to know exactly which methods you're going to use.

You need to document that, yes.  Documenting that you use (or
reserve the right to use in the future) all the methods and
operations of a list is one possibility, but it's surely
not the only one.


> Better to define an interface and ask people to implement it.
>
> I like interfaces with default implementations:
>
>   interface wfile:
>       def write(self):
>           pass
>       write = abstractmethod(write)  # syntax could be better (C:
>
>       def writelines(self, lines):
>           for line in lines:
>               self.write(line)
>
>       def flush(self):
>           pass
>
> [However, I can do without recursive definitions.  Usually,
> one operation is the primitive and the others are sugar.

Actually, it's more frequent that two (occasionally more)
operations need to be in a certain connection with each other,
but none of them is 'intrinsically' primitive wrt the others.

Having to arbitrarily pick one of .append and .extend as
"more primitive" in the definition of a list typeclass is
quite inelegant, for example.

> But even if not, it is still redundant to define x() in terms of
> y() and also define y() in terms of x().  Either definition
> alone suffices to illustrate the relationship.]

Theoretically, perhaps, if the 'definition' is invertible, a
superb and totally hypothetical compiler could infer the other
definition (by definition of 'invertible', I guess:-).  In
practice, *explicit is better than implicit*: better to state
out the 'redundant' case and avoid all difficulty and
ambiguity for both the compiler and the human reader.

I guess this boils down to aesthetic style preferences, but it
seems to me that typeclasses (where default implementations
are allowed to be supplied for all methods in terms of others)
are superior to 'enriched interfaces' (where default
implementations are only allowed for a subset such that the
dependency graph has no loops) by about as much as such
enriched interfaces are superior to 'pure' ones (where default
implementations are disallowed, as e.g. in Java).


Alex






More information about the Python-list mailing list