[Types-sig] A type checking system in Python

Huaiyu Zhu huaiyu_zhu@yahoo.com
Wed, 21 Mar 2001 12:48:36 -0800 (PST)


Thanks to Clark and Robin for encouragement.  I was not aware that type-sig
was active when I wrote those comments and implementation (Aug 2000).  I
just subscribed to it now.  It will take me some time to learn what happened
here lately.  Is there a document that describes the overall goals?  Anyway,
if you see anything useful in my proposal, feel free to adopt it.  That may
be faster than I catch on the other way round.

Now I would like to comment on some of the issues raised by Paul.  I think
my main point is that type checking should be done in a way very similar to
how Python is used today.  It should be much much more flexible than Java.

On Wed, 21 Mar 2001, Paul Prescod wrote:
> "hzhu@users.sourceforge.net" wrote:
> > - It breaks polymorphism.  One has to harness the property at the time the
> >   classes are defined, instead of when they are used.  For example, if an
> >   application requires a property of "ReadableFile" which is satisfied by
> >   sys.stdin, it is difficult to retrofit the definition of sys.stdin to be
> >   an instance of such.
> 
> It is too strong to say it breaks polymorphism. It can in some cases
> *hamper* polymporhism. But Java is a fundamentally polymorphic language,
> as are all other object oriented languages I have used. Polymorphism is
> the central point of OO. Even languages that do not support either
> encapsulation or inheritance support polymorphism.

By polymorphism I mean this.

Define a.                     # in some imported module
Define b.                     # in some other place out of user control
Declare c contains a and b.   # in user code
Require c.                    # then both a or b is acceptable.

In my example, it corresponds to this:

a = sys.stdin     # don't want to change system library
b = open("data")  # passed in as arguement.  don't want to redefine open.
c = ReadableFile  # defined in third party module
f(ReadableFile x)  # the requirement in the module
c.add_obj(a); c.add_obj(b)     # here in user code, after importing a, b, c.
f(a), f(b)        # these should typecheck ok.

This may be more flexible than what is normally called polymorphism.  So
let's call it strong polymorphism.  In any case, it is routinely used in
Python.  It is not supported by Java interface.  In Java, I do not believe
you can define an interface in user code, and then retro-actively declare
that some imported class satisfy this interface.  I would not want a
typechecking system in Python without strong polymorphism.

> 
> > - It mixes two incompatible inheritances.  For example, suppose that class A
> >   has method A.m() but its subclass B overrides it with B.m().  The property
> >   A satisfies is not necessarily satisfied by B.
> 
> You cite Java interfaces above and yet Java interfaces are *specifically
> designed* to separate out the two different kinds of inheritance. That's
> why there are interfaces which are distict from classes!

It is closer to the truth to say it this way: 1. Java allows multiple
inheritance, but only one superclass may contain any implementation.
2. Those classes without implementation are called interface.  So yes, Java
interefaces are not meant for implementation.  On the other hand, the design
is not right for requirement, either.  It is lame.

The distinction in my proposal is that Types (or call it interfaces if you
like) should inherite the other way round.  When you check

a is of Type b

you should not ask a: "Are you of type b?"  You should ask b: "Do you
include a?"

In a good design, an object should be able to satisfy an infinite number of
interfaces, most of which do not yet exist, without knowing anything about
them.

> 
> > From the above it is clear that there is a useful conceptual hierarchy that
> > is independent of the class hierarchy.  For lack of a better name let us
> > just call them Types.  
> 
> We've been calling them interfaces and/or protocols. Python already has
> a meaning for "type" which is somewhat confusing in this context.

I really don't know what a suitable name should be, despite thinking hard on
this.  Calling it "interface" gives a wrong association with Java, which is
fundamentally different.  "protocol" may be good, except it gives the
impression that it actually checks a certain behavior.  It should be able to
do that, but it should not be mandatory.

> 
> > - classes embody implementations
> > - Types embody requirements
> 
> This is exactly the distinction between Java classes and interfaces. I
> have a prototype implementation that embodies this distinction here:

But Java did not do it right!  For requirement specifications, it should not
be inherited in a way similar to class.  Especially, it should not be
specified during definition.

> 
> http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/python/nondist/sandbox/typecheck/?cvsroot=python

I just glanced over this.  Is there a text description of this?  From what I
see, it seems that you want the types be predefined.  Can the user add type
later on and declare whatever object he has as being of this type?

> 
> We've been discussing these issues in the type-sig. You are invited to
> join us there. 

Glad to join here.  Does Guido read here?

Huaiyu Zhu <hzhu@users.sourceforge.net>