Python 1.6 The balanced language

Neel Krishnaswami neelk at
Sun Sep 3 18:48:16 CEST 2000

Alex Martelli <aleaxit at> wrote:
> "Neel Krishnaswami" <neelk at> wrote in message
> news:slrn8r4qej.b6p.neelk at
> > Alex Martelli <aleaxit at> wrote:
> > >
> > > "subtyping exists" is another contentious issue, of course; if I
> > > removed "extends" from Java, requiring all polymorphous use to
> > > go through "interface" and "implement" (as, e.g., Coad has suggested
> > > as best design practice), would I "totally lose OO-ness"?
> >
> > No, because you still have subtyping. You've taken away inheritance,
> > but that's not the same thing (see Sather for a rather graphic
> > illustration of the difference).
> If by subtyping you mean the java 'implements', then, yes.  But to
> call the signature-based polymorphism of Python "subtyping" is
> starting to stretch the meaning of the word -- yet, it's at least
> equivalent to what interface+implements lets you do, modulo
> the compile-time checks.

Not really. If you create a class (call it Foo) with all the methods
of an interface (call it Bar) but you don't specifically declare the
"implements" relation, then you can't use Foo in the place of a Bar.
The classes that implement an interface are all subtypes of the type
the interface creates, and no other classes are subtypes of that

> I say that OO == polymorphism, aka, runtime dispatching.  If it's
> done through subtyping, signatures, prototypes, etc, is quite a
> secondary issue.

Mostly, yes. I would want to distinguish parametric polymorphism (a la
ML) from the dynamic method lookup in OO languages. (It's possible to
combine both, of course, as in Python and other dynamically typed

> > You still have types as a semantic concept in Self and Cecil, though.
> > A type object is one which other objects name as a delegate; grab all
> > the objects that delegate to it and you have all its direct instances.
> >
> > The fact that an object's type can change over its lifetime isn't a
> > disqualification. Note that this isn't that foreign to Python, either:
> > you can change an object's class by setting the __class__ field, and
> > you can change the inheritance graph by setting __bases__.
> In Python, a class object plays a very specific role -- it knows it's
> a class, its role in life is to generate instances and provide a shared
> namespace/dictionary for them.  An object which is named as a
> delegate in Self has no such specialness.  

That specialness is lost when you move to a class-based language with
metaclasses; it's not an intrinsic property. What is intrinsic is the
notion of type -- whether the type relation is "instance of" for
class-based languages or "descendant of" for object-based languages.

> Similarly, say the Cecil authors, "Cecil uses a classless
> (prototype-based) object model" (e.g., cf
>  And one must not confuse
> argument-specializers, with type-declarations (the latter do not
> affect method-lookup in Cecil).

What I mean by "type" is equivalent to the Cecil "isa" keyword. This
is just the descendant-of relation.

> Are you saying that they're wrong, that it's NOT 'classless'?  Or do
> you accept that claiming 'classes' are a prereq for O-O, as the
> poster I was responding to did, is simply wrong?

Types in Cecil are real. It doesn't have classes. I don't see a
problem here. :)

> Of course you can identify at any moment in time various sets of
> object-instances that have something in common (e.g, they all
> delegate something to a given object X; or, they all happen to live
> entirely on a given page of virtual memory; or, they're all
> referencing a certain string S; etc, etc).  But to call such sets
> 'types' (whatever rule you choose to identify the dynamically
> changing set[s]) is not particularly enlightening -- and to call
> them 'classes' is worse... 'disinformation'!-)

I disagree quite strongly. The notion of type is extremely useful even
in prototype based languages. It allows us to formalize the notion of
(for example) mode switching, which is an extremely elegant style of

Basically, you can use dynamic inheritance to change an object's
methods to match its current state. For example, rather than putting
in an explicit test for whether the stream is open or closed in the
object's methods, you can write two sets of methods, one for each
case, and then change which set it uses whenever the open/closed state
changes. This is nicely conceptualized as the following inheritance

     |           |
  openfile   closedfile

with the observation that the object's type changes at runtime. 


More information about the Python-list mailing list