[Types-sig] Interface PEP

Marcin 'Qrczak' Kowalczyk qrczak@knm.org.pl
14 Mar 2001 21:37:34 GMT


Wed, 14 Mar 2001 20:53:05 +0100, Sverker Nilsson <sverker.is@home.se> pis=
ze:

> Well, what I can agree with is that the interfaces are _descriptions_:
> more for the human reader, than for (dynamic or static) type-checking.

They are both for humans and for the interpreter / compiler.

> I could consider the type of an object to be something different
> than the interface, but then _also_ different from the class,
> contrary to what you imply below.

There are always problems with underspecified terminology. Especially
the area of types, classes, interfaces, subtyping / subclassing /
inheritance, polymorphism is really confusing... The same terms are
used in the context of different systems or languages with different
meaning. Easy to be confused or misunderstood.

Python uses terms "type" and "class". There are several builtin
types. Object created as class instances all have the same type
(InstanceType), and can be further distinguished by their classes.
Many people agree that it would be cleaner to unify these concepts
in future.

C++ uses terms "type" and "class". There is a similarity to Python's
usage, but in C++ there is no single InstanceType: some types are
classes, some are not classes. Class templates aren't types yet.

Eiffel uses terms "type" and "class". Class is the basic unit of
modularity (how an object is defined), type describes an interface
(what do we expect from an object). Each non-parametrized class
yields a type. Each parametrized class may yield a type when applied
to appropriate arguments.

Haskell and Clean use terms "type" and "class". Type defines an
implementation and functions often require a concrete type. Class
defines an interface. Types may conform to classes. Functions may also
require that the type of their argument conforms to some classes. This
is quite backwards compared to Eiffel and OO theoretic terminology.
Parametrized types are unified with types, i.e. types of concrete
objects are special cases of parametrized types in general.

OCaml uses terms "type" and "class". Type defines an implementation and
functions often require a concrete type. The OO subsystem introduces
classes (templates of objects with method definitions) and class types
(interfaces of objects with method signatures). A class type is a type.
A class is something between an object and a type. I hope I got it
right - I don't have an experience with OCaml's OO subsystem.

We have plenty of definitions to choose from :-)

> > Interfaces".  One class, or "type" of object, can implement multiple
>=20
> So you identify the object's class with its type... why?

In Python they have the same purpose. A type, combned with a class
(in case of InstanceType), describe the implementation of an object.
Well, partially: object attributes can be different for each object.

Interfaces of objects are not described formally in Python nor checked.
One of current goals is to change this.

> Well I'd say "lots of different _classes_ of objects.."
> Not types of - that would again prematurely fix what we mean
> with the type of an object.

I assume that we use the term "type" as currently defined in Python,
and don't change that.

> I'd say SequenceType or MappingType should be types just as well
> as ListType.  Why make them different kinds of things?

ListType describes an implementation, i.e. how an object was
constructed. There is a particular object layout and particular
methods.

SequenceType describes an interface, i.e. how an object can be used.
An interace can include things that "len(o) is defined and means blah
blah" - it doesn't matter how len is dispatched.

> I'd say ListType is a _subtype_ of SequenceType.

A basic misunderstanding of some languages is confusing subtyping
(the ability to use one type if another is required, i.e. a relation
on interfaces) and inheritance (basing a class definition on another
class, i.e. reusing the implementation).

Eiffel has problems because of this. It requires checks of the whole
assembled system to see if a subclass yields a subtype or not.

C++ and Java have lack of expressiveness because of this. They
require some casts because a method signature can't change in an
inherited class.

I don't say that you claim that subtyping is the same as inheritance.
But you try to unify types / classes with interfaces, which doesn't
work well.

A type / class may generate an interface requirement: namely that an
object is of this class or a subclass (the "or a subclass" part is
very problematic). An interface may generate a type / class definition:
we may want to hold an arbitrary object conforming to an interface.
They are sometimes blurred, but they are definitely different concepts.

We can have two interfaces (e.g. "comparable" and "convertible to
a string"). One object conforms to the first but not to the second,
another conforms to the second but not to the first. This situation
cannot be described by locating the object's type in the interface
tree and checking its supertypes. It's not a tree.

--=20
 __("<  Marcin Kowalczyk * qrczak@knm.org.pl http://qrczak.ids.net.pl/
 \__/
  ^^                      SYGNATURA ZAST=CAPCZA
QRCZAK