OO in Python? ^^

Magnus Lycka lycka at carmen.se
Tue Dec 13 05:37:04 EST 2005


Welcome to Python Matthias. I hope you will enjoy it!

Matthias Kaeppler wrote:
> Another thing which is really bugging me about this whole dynamically 
> typing thing is that it seems very error prone to me:
> 
> foo = "some string!"
> 
> # ...
> 
> if (something_fubar):
>    fo = "another string"
> 
> Oops, the last 'o' slipped, now we have a different object and the 
> interpreter will happily continue executing the flawed program.

As an old hardware designer from the space industry, I'm well
aquainted with the idea of adding redundancy to make things
more reliable. I also know that this doesn't come without a
prize. All this stuff you add to detect possible errors might
also introduce new errors, and it takes a lot of time and
effort to implement--time that could be spent on better things.

In fact, the typical solutions that are used to increase the
odds that hardware doesn't fail before its Mean Time To
Failure (MTTF), will significantly lower the chance that it
works much longer than its MTTF! More isn't always better.

While not the same thing, software development is similar.
All that redundancy in typical C++ programs has a high
development cost. Most of the stuff in C++ include files
are repeated in the source code, and the splitting of
code between include and source files mean that a lot of
declarations are far from the definitions. We know that
this is a problem: That's why C++ departed from C's concept
of putting all local declarations in the beginning of
functions. Things that are closely related should be as
close as possible in the code!

The static typing means that you either have to make several
implementations of many algorithms, or you need to work with
those convoluted templates that were added to the language as
an afterthought.

Generally, the more you type, the more you will mistype.
I even suspect that the bug rate grows faster than the
size of the code. If you have to type five times as much,
you will probably make typos five times as many times,
but you also have the problem that the larger amount of
code is more difficult to grasp. It's less likely that
all relevant things are visible on the screen at the same
time etc. You'll make more errors that aren't typos.

Python is designed to allow you to easily write short and
clear programs. Its dynamic typing is a very important
part of that. The important thing isn't that we are
relieved from the boring task of typing type declarations,
but rather that the code we write can be much more generic,
and the coupling between function definitions and function
callers can be looser. This means that we get faster
development and easier maintenace if we learn to use this
right.

Sure, a C++ or Java compiler will discover some mistakes
that would pass through the Python compiler. This is not
a design flaw in Python, it's a direct consequence of its
dynamic nature. Compile time type limitations goes against
the very nature of Python. It's not the checks we try to
avoid--it's the premature restrictions in functionality.

Anyway, I'm sure you know that a successful build with
C++ or Java doesn't imply correct behaviour of your
program.

All software needs to be tested, and if we want to work
effectively and be confident that we don't break things
as we add features or tidy up our code, we need to make
automated tests. There are good tools, such as unittest,
doctest, py.test and TextTest that can help us with that.

If you have proper automated tests, those tests will
capture your mistypings, whether they would have been
caught by a C++ or Java compiler or not. (Well, not if
they are in dead code, but C++/Java won't give you any
intelligent help with that either...)

I've certainly lost time due to mistyped variables now
and then. It's not uncommon that I've actually mistyped
in a way that Java/C++ would never notice (e.g. typed i
instead of j in some nested for loop etc) but sometimes
compile time type checking would have saved time for me.

On the other hand, I'm sure that type declarations on
variables would bring a rigidity to Python that would
cost me much more than I would gain, and with typeless
declarations as in Perl (local x) I would probably
waste more time on adding forgotten declarations (or
removing redundant ones) than I would save time on
noticing the variable mistypings a few seconds before
my unittests catch them. Besides, there are a number
of lint-like tools for Python if you want static code
checks.

As I wrote, the lack of type checking in Python is a
consequence of the very dynamic nature of the language.
A function should assume as little as possible about
its parameters, to be able to function in the broadest
possible scope. Don't add complexity to make you code
support things you don't know of a need for, but take
the chance Python gives you of assuming as little as
possible about your callers and the code you call.

This leads to more flexible and maintainable software.
A design change in your software will probably lead to
much more code changes if you write in C++ than if you
write in Python.

While feature-by-feature comparisions of different
programming languages might have some merit, the only
thing that counts in the end is how the total package
works... I think you'll find that Python is a useful
package, and a good tool in a bigger tool chest.



More information about the Python-list mailing list