[Types-sig] Static typing: Towards closure?

Guido van Rossum guido@CNRI.Reston.VA.US
Thu, 20 Jan 2000 17:31:04 -0500


> I) Beware of overloading ':' too much.

Point taken.

> decl foo the integer
> 
> def foo(a the string, b the Bar) -> integer:
>     pass

I don't like this; the colon still looks best to me.

> II) The stubbing problem.

> def foo(a, b) -> integer:
>    pass
> 
> will presumabily cause the typechecker to barf. I'm not quite sure if this
> is really bad, but I just wanted to bring it to people's attention.

Do this the same say as in Java or C++: return a dummy value.

> III)
> 
> My previous point implies in my mind an important principle:
> 
> When adding type checking to Python, the speed of developing in Python should
> *not* go away. If static type checking makes us slow down too much, we
> will have failed.
> 
> This splits into two requirements:
> 
> * We want to keep Python as it is today. We want to avoid the chance that
> static types run amok, subtly or non-subtly pushing people to add them
> everywhere, as this could slow down development a lot.

Point taken (Skip also warned about this).

> * We want statically checked Python to be as much as possible like Python
> today in regards to quick development time. Ideally Python with type
> annotations should not be that much slower to develop in than Python without.

Actually, we would expect it to be faster, because errors are caught
earlier (during code generation rather than during testing or when in
production) and this should save time.

Of course there's more typing (I'd say about 10% more).

> My next point is influenced by this important principle as well.
> 
> IV) interfaces

> Interfaces can be implied:
> 
> class Foo implements Alpha:
>     decl greeting: integer
> 
>     def hey(a: integer)->integer:
>         ...
> 
>     def hi(a: string)->string:
>         ...
> 
>     def hoi(a: float)->float:
>         ...
> 
> class Bar implements Alpha:
>     
>     decl greeting: integer
>     decl specialgreeting: integer
> 
>     def hey(a: integer)->integer:
>         ...
> 
>     def hi(a: string)->string:
>         ...
> 
> Alpha is now deduced to be the following interface:
> 
> interface Alpha:
>     decl greeting: integer
> 
>     def hey(a: integer)->integer:
>         ...
> 
>     def hi(a: string)->string:
>         ...
> 
> Note that you don't need to write this down anywhere! It's implicit
> (until explicitized by the developer).

Urk!  This defeats the purpose of static checking; it's no better than
not using static checking at all!

> The consequences:
> 
> * no need to explicitly code up interfaces, so existing Python code is
> more easily brought into a typecheckable form. You could for instance 
> say each FileObject type class implements the interface FileObject.

There are lots of subtleties, and I *like* the idea of an explicitly
specified interface to disambiguate what is a file (e.g. must it have
seek()?  fileno()?  isatty()?).

> * no need for access specifiers; private members are implied as they
> usually won't appear in both classes, and are thus not part of the 
> interface.

Waiting for accidents to happen (unrelated variables that happen to
have the same name).

> * interfaces are easily shrunken if necessary, by declaring a special class
> with the maximum interface.
> 
> * interfaces can always be made explicit (and then any class that states it
> conforms to it but doesn't is in error), so that a minimal interface can
> be specified.
> 
> These consequences may be advantages during development; interfaces (or types)
> can be quickly and conveniently created and used, and they are always 
> _right_; we're not bothered by interface compliance errors as the interfaces
> are implied.
> 
> This is good as early in development we may still be prototyping, and 
> therefore we may not be clear on the exact structure of the interfaces
> yet. We don't want to go back and forth to change the interface definition 
> all the time as we discover new methods are needed, or some should be removed.
> We only have to edit the actual classes implementing the interface.
> 
> As the code solidifies we may want to do more checking, so we
> can start to explicitize the interfaces. This is similar to the pattern we're
> hoping to accomplish by adding static typechecking -- it should be possible
> to code in the dynamic way and then tighten up code by adding type annotations
> later.

It sounds like a much better thing to do is to leave out all type
declarations during prototyping, and add them as you start agreeing on
what the interfaces should be.

> I posted earlier to the list on this idea, but either nobody read it,
> nobody understood it or everybody thought it was obviously a bad idea. I'd
> like to be informed on which is the right explanation. :) 

My-guess-is-it-was-obvious-ly y'rs,

--Guido van Rossum (home page: http://www.python.org/~guido/)