I come not to bury C++, but to praise it...

Andrew Koenig ark at acm.org
Thu Jan 15 10:53:25 EST 2004


> The argument runs like this: If you don't have near-100% test
> coverage, you are missing many bugs that static typechecking will not
> catch.  So don't do that (the fact that it's perfectly feasible to
> have near-100% coverage, when given support from bosses where
> relevant, has been repeatedly demonstrated recently).  OTOH, if you do
> have 100% coverage, the set of bugs that *are* caught by the static
> typechecks, but *not* by the tests is usually very small, in practice.

There is a subtle fallacy in this argument, at least in the context of C++
and Python, namely that there is a significant category of errors that
static type checking (as C++ and some other languages do it) can detect but
can escape even 100% test coverage.

Before you get out your flame-thrower, please hear me out -- I am not saying
that this reasoning applies to all errors, or even a majority of them, but
only to a significant category.  That category consists of programs where
the types of key objects are not known when the program is written, but are
known when the program is compiled.

Here's an example.  Suppose you're writing a library sort function, which
you intend to be able to work with any kind of sequence.  Suppose further
that you test it only with vectors.  Then you might well have 100% test
coverage, but the code might break when you call it with another kind of
sequence, because it relies on some property of vectors that not all
sequences share.

In practice, C++ programmers often solve such problems by using templates,
which defer type checking until the last possible moment during the
compilation process.  In effect, the compiler looks at each call to our
hypothetical sort function, and verifies that the type assumptions that the
sort function makes are valid in the context of that particular call.  The
result is that the compiler can detect type errors that would show up in a
dynamically typed environment only if the function were tested with the
specific types that revealed the error.

The price one pays for this extra checking, of course, is that one cannot
call such a sort function with an argument with a type that is known only at
run time.  But in practice, there are many cases where being able to defer
type checking until the end of compilation is just as useful as being able
to defer it until run time.  I believe that many people who dislike static
type checking are unaware of this distinction.





More information about the Python-list mailing list