"Strong typing vs. strong testing"

Lie Ryan lie.1296 at gmail.com
Thu Sep 30 07:38:28 CEST 2010

On 09/30/10 11:17, Seebs wrote:
> On 2010-09-30, RG <rNOSPAMon at flownet.com> wrote:
>> That the problem is "elsewhere in the program" ought to be small 
>> comfort.
> It is, perhaps, but it's also an important technical point:  You CAN write
> correct code for such a thing.
>> int maximum(int a, int b) { return a > b ? a : b; }
>> int main() {
>>   long x = 8589934592;
>>   printf("Max of %ld and 1 is %d\n", x, maximum(x,1));
> You invoked implementation-defined behavior here by calling maximum() with
> a value which was outside the range.  The defined behavior is that the
> arguments are converted to the given type, namely int.  The conversion
> is implementation-defined and could include yielding an implementation-defined
> signal which aborts execution.
> Again, the maximum() function is 100% correct -- your call of it is incorrect.
> You didn't pass it the right sort of data.  That's your problem.

That argument can be made for dynamic language as well. If you write in
dynamic language (e.g. python):

def maximum(a, b):
    return a if a > b else b

The dynamic language's version of maximum() function is 100% correct --
if you passed an uncomparable object, instead of a number, your call of
it is incorrect; you just didn't pass the right sort of data. And that's
your problem as a caller.

In fact, since Python's integer is infinite precision (only bounded by
available memory); in practice, Python's version of maximum() has less
chance of producing erroneous result.

The /most/ correct version of maximum() function is probably one written
in Haskell as:

maximum :: Integer -> Integer -> Integer
maximum a b = if a > b then a else b

Integer in Haskell has infinite precision (like python's int, only
bounded by memory), but Haskell also have static type checking, so you
can't pass just any arbitrary objects.

But even then, it's still not 100% correct. If you pass a really large
values that exhaust the memory, the maximum() could still produce
unwanted result.

Second problem is that Haskell has Int, the bounded integer, and if you
have a calculation in Int that overflowed in some previous calculation,
then you can still get an incorrect result. In practice, the
type-agnostic language with *mandatory* infinite precision arithmetic
wins in terms of correctness. Any language which only has optional
infinite precision arithmetic can always produce erroneous result.

Anyone can dream of 100% correct program; but anyone who believes they
can write a 100% correct program is just a dreamer. In reality, we don't
usually need 100% correct program; we just need a program that runs
correctly enough most of the times that the 0.0000001% chance of
producing erroneous result becomes irrelevant.

In summary, in this particular case with maximum() function, static
checking does not help in producing the most correct code; if you need
to ensure the highest correctness, you must use a language with
*mandatory* infinite precision integers.

More information about the Python-list mailing list