[Types-sig] Why I don't like static types in Python

Dominic Binks dominic.binks@aethos.co.uk
Fri, 27 Nov 1998 17:52:35 +0000


Justus Pendleton writes:

> 
> All in all, those are, in my opinion, thoroughly unconvincing arguments.
> 

> 1.  Static types can improve readability by making the programmer's
>     intentions more explicit,
----
> 1.  I don't think that static types really improve readability in any way
> whatsoever.  The problem?  The type is only shown when the variable is
> declared, not every time it is used.  Even though C is statically typed lots
> of people use Hungarian notation to get around this very problem.  If we are
> really interested in increasing the readability of programs by making the
> programmer's intentions more explicit then why don't we develop a Dutch
> naming scheme and use that (i.e. port_h [h => heel]) instead?

True, but if types are in a kind of prototype, you know where you can
look for the order of arguments, what return type is expected etc.  As a
programmer, trying coding C without header files declare prototypes. 
Also trying making sense of C function man pages without type
information.  This information provides instructions on what should be
provided as arguments.  In C you can get away with (as far as the
compiler is concerned) sticking almost anything in the arguments to a
function, but the prototype tells you if you stick wrongly typed
arguments into the functions you are at very best relying on undefined
behaviour and at worst you are shooting yourself in the foot.  Python is
slightly different in this respect because portability is not an
immediate problem, since the interpreter takes care of it, but I have to
look up the manual to find out the order of arguments for any function I
wish to use.  A prototype would save me this.  I know you can read the
code, but this is not in general a valid answer to the problem.

> 2.  Optimize for increased performance,
> -------------------------------------------------------------------------
> 2.  I agree with Skip Montinaro's comments that it's not clear we've come
> close to exhausting the performance possibilities of Python as it currently
> exists.  He and others have pointed out other interesting avenues to explore.
> If performance is the concern then I think rather than changing the syntax in
> any way we should first try to make nonvisible changes.  Maybe there could be
> some kind of JIT compiler for Python, I dunno.  Would it be possible for
> there to be a Python compiler that does global analysis of the entire program
> and then does some magic type inferencing and dynamic code recompilation to
> notice that var is only ever assigned integers and then generate appropriate
> byte code for that situation?
> 
> What's more, I'm not convinced that performance is such an issue.  I'm
> sure that other people have had other experiences, but at my work the only
> times that speed has ever mattered it has mattered so much that Python could
> never possibly be a contender no matter how fast it is.  When Python is
> playing the role of a glue or an extension language, it's already fast enough
> for every use I've ever seen.  On the other hand, even if we do nothing
> Python will be twice as fast next year as it is this year.  How fast is fast
> enough?  How slow is too slow?
> 
> More to the point, how much will static typing in Python actually affect
> these things?  Would we be willing to add a change as major as static typing
> for a 10% speed increase?

This is all true but I think in tight loops you see much more than a 10%
increase in performance.  The tricks that Skip describes in his
optimisation hints include precisely the kinds of optimisations that a
compiler which was type aware could perform automatically: i.e. avoid
dictionary lookups for names which is the single most important aspect
of enhancing the performance of a Python application (assuming the
algorithm is good!).


> 3.  For detecting type errors,
> -------------------------------------------------------------------------
> 3.  Roger Masse writes that static typing provides an 'improved level of type
> safety and program correctness' but I'm not aware of any empirical evidence
> of this.  Is this just simply "common sense"?  I am wary of "common sense"
> that is lacking an empirical foundation.  Don't forget that for many people
> it was "common sense" that the earth was flat, that the earth was the center
> of the universe, and that maggots spontaneously generated from rotten meat.
> Why should we rush to change our favorite language when their is no proof
> that doing so will provide the benefits we claim we want?
> 
> Is a strongly typed system actually safer in any way whatsoever?  As Dave
> Beazley asks, "are there really huge numbers of people out there writing
> unreliable Python programs? Is type-safety going to solve their problem even
> if it were available?"  Why add a language feature that doesn't solve a
> problem?  C is a weakly typed language but people still seem to be able to
> create "safe" systems in it....
> 
> IMHO there would be some problems with static typing in Python anyway.  Would
> the static type system catch something like the following:
> 
> ====================================
> def myCallable( d : MyClass):
>         return d.my_method()
> 
> val : MyClass
> val = MyClass()
> del val.my_method
> myCallable(val)
> ====================================

To use an similar example from C:

struct my_struct {
	char *my_string;
};

...

	struct my_struct val;

	val.my_string = strdup("Hello World!");

	free(val.my_string);
	
	printf("%s\n", val.my_string);

Ok it's not a function, but the basic argument is the same.  Runtime
ordering of operations cannot obviously be detected by the type system. 
It isn't there to do that.  It is there to try to assist the programmer
in detecting areas where they've (inadvertantly) passed the wrong
argument to a function/method.

[Further more reasonable arguments removed]
> 
> "More importantly, how do you gain confidence that an implementation of a
> file-like object has implemented seek in the way you think it ought to
> implement seek without running it?"

So the question ends up does it not make sense that two methods in two
objects that have the same name do the same thing using the same
arguments.  Surely it makes sense if seek make sense in my file like
object it makes sense that it takes the same arguments as the seek in
the file object (meaning that I can replace the file object with my
file-like object).

> 
> In short, I don't think that static typing gives you a whole lot in terms of
> safety...certainly not enough to warrant adding the feature to the core
> language, even as an optional one.  If we had Design By Contract in Python
> (with inherited assertions and so forth) would that be sufficient to satisfy
> our needs for safety?

A bit of background about what we use Python for.  We use it as a kind
of glue, kind of RAD tool.  It provides an interface for other systems
to add/query/modify/delete customers to our system.  It allows us great
flexibility and ease of fixing problems, new featiures etc.  It takes
about a day to provide support for a new operation (i.e. add or query)
and about week to debug it.  Probably about half of that can be placed
at easily checkable static conditions, type correctness being one of the
most important (usually because it's often hard to locate).

I have suffered because of Python's lack of type system and yet even a
primitive system that says this function should take a string and you've
given it an integer would have saved me and my team many hours.

Finally I'd like to add that it may be impossible to do something that
covers the whole of Python.  eval() for example presents some real
problems for any type system to provide any real safety.  However what
can be done can save some valuable amount of development time.

> 4.  The existing type system in Python is nice for development within small
>     groups but is not well suited for large-scale development because of the
>     difficulty in specifying a common interface without implementation to
>     convey behavior.
-------------------------------------------------------------------------
> 4.  I agree that specifying an interface without the implementation would be
> nice for larger projects.  But couldn't that same kind of information be
> generated by some documentation tool like interdoc or whatever the docutils
> people have cooked up?

Yes, but how can you tell what type the arguments of a function/class
should be without the type system.  Yes you can use the type checks that
Python allows you to do, but that means much extra complexity in the
autodoc tools.  The prototypes would be additional the document strings.


>  Shouldn't people be reading the documentation for the
> code rather than the code anyway?  Why would we want to encourage people to
> bypass the documentation and read the code directly?  Why would we want to
> encourage skimping on documentation?  It seems that adding static typing to
> Python as a way of providing documentation to Python code is somewhat
> misguided.  Instead shouldn't we use __doc__ strings with structured
> formatting?
> 

But that still won't guard against putting an integer into a
function/method that is expecting a string.

> -------------------------------------------------------------------------
> In short my complaints about static typing (and protocols/interfaces, I
> suppose) are that I don't see what problems these new features would solve
> that currently available features can't.

Probably nothing.  It's more a question of ease of use.  It makes much
more sense to provide an interface to check types rather than at runtime
(reduced overhead in time) and implementors will not always do what they
should do.  Providing an interface ensures that they will at least
instruct a compiler to do the checks.

>  I think there are definitely ways
> that Python can improve and grow, I just don't think that static types are
> one of those ways.  I look forward to hearing what proponents of static
> typing and protocols think about this.
> 

I'd love to see type inference.  I know that seems to be a dirty word
around the Python community but it certainly works really well in
functional languages and costs nothing t implement for implementors. 
For Python it could easily be just a tool, that way you don't use it if
you don't want to.

Just my 2p

Dominic

-- 
Dominic Binks/Systems Engineer/Aethos Communication Systems Ltd.
400 Park Avenue/Aztec West/Bristol/BS32 4TR/United Kingdom
Tel: +44 1454 614455/Fax: +44 1454 620527/Mobile: +44 498 693964
E-mail: dominic.binks@aethos.co.uk