[Types-sig] Interface PEP

Sverker Nilsson sverker.is@home.se
Thu, 22 Mar 2001 16:54:51 +0100


Marcin 'Qrczak' Kowalczyk wrote:
> 
> Wed, 21 Mar 2001 17:55:57 +0100, Sverker Nilsson <sverker.is@home.se> pisze:
> 
> > How about the type() builtin. I assume we can't remove it or rename
> > it to class() because it may break too much code. What should it
> > return for an instance of a user-defined class then?
> 
> Deprecate it. Let it behave as currently, but it has no place when
> types and classes are unified. Have another function which returns
> the unified type/class of an object.

With the metaclass() I talked about in the previous mail, you can do
this. To return the class of an object:

def class_of(obj):
    t = type(obj) 
    if t is InstanceType: return obj
    else: return metaclass(t)

type() would still exist. If you manage to 'depreciate' it good luck
for you, but I wouldn't think you will have succeed. Backwards
compatibility is very important - Already for minor things but
depreciating, removing type() would be a major thing.

> 
> Or change it. Let it return the class object instead of InstanceType.
> Use from __future__ or another mechanism to make the transition smooth.

There is really no smooth transitions, and especially not with this
big a change, I would say.

> 
> I don't care. I'm not talking how to smoothly apply this unification

That's an important constraint of this discussion though.  If we could
make backward-incompatible changes in this scale, where would the
limit be? I'd say we could as well design a new language from scratch.

> to existing Python, but how a Python with unified types+classes would
> look like.

As I indicated, you can get the look and feel you want using class_of
that I showed above. You won't need to use type() for new programs.
Just remove it from __builtins__ and remove types.py and you are done!
(Provided class_of is implemented in C so it doesnt use type(), minor
detail!)

> 
> > Granted, he seem to regard this mostly as a temporary solution,
> > but I don't see why it can't be part of the permanent solution.
> 
> Because the special status of builtin types is only an artifact of the
> current implementation. The split doesn't carry a meaningful message.
> The same thing can be often done as either type or class.

I dont agree of (or understand) this, but even if I did, it seems
irrelevant since as I showed above you get the equivalent effect
anyway.

> 
> > Builtin Python types happen to specify specific implementations.
> > I still don't see why we can't have something more we call types,
> > user define types, that happen to specify another implementation
> > (such as the implementation shared by all InstanceType objects)
> > but mostly are used to specify a protocol/interface.
> 
> Because interface is the opposite of implementation!

In some way, perhaps.

> 
> The point in an abstract interface is that it does not say anything
> about the implementation.

Now you are talking about 'abstract' interfaces, I was referring to
interfaces in general. Well ok, I will let you use your definition,
wherever it comes from. It doesn't change much though.

> 
> A type defines an implementation (and indirectly some interface,
> but parts of this interface are shared by many types and classes).

I could likewise invent something like 'abstract' type and say the
point of it is to not say anything about implementation.

I don't agree that a type needs to specify an implementation. It can,
but not necessarily. For me, type is a general term that can be used
to specify anything at all.  I'd say it is just a set of
objects... although some hard-core mathematical / CS people may
perhaps have some objection.

> 
> A class defines an implementation (and indirectly some interface,
> but parts of this interface are shared by many types and classes).

I agree.

> 
> An interface doesn't restrict the object to have a particular type or
> class. It only says how the object can be used. Interfaces are not

I'd be able to agree. And add, a type is more general.

> formalized in Python, but could be, and the purpose of this list is
> to design an interface framework and concrete interfaces in it.

The purpose of this list is not limited to interfaces, but types
in general, IMHO.

> 
> Type and class are almost the same concept.

No. Class is much more specific than type.

> Interface is a completely different concept.

I agree.

> 
> > That said, I believe it would be good to have a single way to
> > refer to what we put as the type-indication. If we have this syntax
> > for example:
> >
> > def f(x:y)
> >
> > What's the y? Most languages call it a type, I think.
> 
> It doesn't matter how they call it. It matters what it means.
> 
> Since it determines what f assumes about x and which objects
> are acceptable for x, it seems natural to call it an interface.

I don't agree. It is too constraining to require that you only can
specify an interface here. Maybe it's good for polymorfism, but we
shouldn't force that on the users in this way. A function may
legitimately require more of its parameters than just an interface. It
may legitimately require a specific implementation of list or sequence
that has certain time and space properties for certain operations. Etc.

So I see it as more natural to call it a type, not imposing any
implied or enforced restrictions on what you can specify.

> 
> For example "sequence" and "file-like object" are already existing
> Python interfaces, even if not strictly defined.

Types that specify certain interfaces, I'd say.

> 
> If f indeed requires x to be a specific type or class, and it's
> not enough for x to have specific methods with specific signatures
> and meanings, we can make an interface from a type or a class. Such
> interface is quite constraining: it requires an object to have the
> specific type or inherit from the specific class.

It would stretch the meaning of interface too much to require it to be
able to specify everything. You'd be better off just calling it a type,
not imposing any implied restrictions that you nevertheless will work
around.


> For convenience we can allow type objects and class objects to be
> used as interfaces directly, instead of having to explicitly obtain
> the interface generated by a type or class.

This seems wrong. Starting with a specific term 'interface' and then
allow different terms, general or specific, to be used in its place -
doesn't make sense to me.

The right way would be to start with a general term, 'type', and then
allow more specific things.

This is assuming type is really a general term. You seem to mean it
always has to specify an 'implementation'. I don't know where you get
that notion?

The following quote doesn't say anything implementation of a type.

    The notions of type and class are often confounded in
    object-oriented programming languages. In fact they play quite
    distinct roles, and can be usefully distinguished from each
    other. Types provide interface information that determines when
    certain operations are legal, while classes provide implementation
    information including the names and initial values of instance
    variables and the names and bodies of methods.

From: Kim Bruce: Typing in object-oriented languages: Achieving 
expressiveness and safety.  http://www.cs.williams.edu/~kim/README.html

BTW, I found that reference in GvR's typechecking proposal:

http://www.python.org/~guido/Proposal.txt

[Snip. Haskell typing discussion] 

Not going to dive into deeper technical discussions about Haskell, for
now. Thanks for the explanation. I still find it strange and
constraining but that may just be me.

[Snip, explanation of some differences of what you can do in Java,
Eiffel and Haskell]

Ok, I don't have any more opinions that I wish to speak about now :-)

Regards,

Sverker Nilsson