Newsgroups: comp.lang.misc
Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!batcomputer!cornell!rochester!kodak!islsun!cok
From: cok@islsun.Kodak.COM (David Cok)
Subject: Re: Run-time Type Errors in Smalltalk
Message-ID: <1991May16.175340.25522@kodak.kodak.com>
Sender: news@kodak.kodak.com
Organization: Eastman Kodak Co., Rochester, NY
References: <1991May15.141839.20603@daffy.cs.wisc.edu> <1991May16.011804.21042@tkou02.enet.dec.com> <1991May16.134106.24421@daffy.cs.wisc.edu>
Date: Thu, 16 May 91 17:53:40 GMT

In article <1991May16.134106.24421@daffy.cs.wisc.edu> quale@saavik.cs.wisc.edu (Douglas E. Quale) writes:
>For instance, I recently spent more than a couple of minutes figuring out
>what was wrong with a C program with this fragment:
>
>{
>	...
>	double f, foo;
>	int i;
>
>	...
>
>	f = modf(foo, &i);
>	...
>	switch (i) { ... }
>}
>
>This is a type error that the $%#!!% compiler didn't catch (Yes, I did
>include math.h).  All that was done with i was to use it in a switch
>statement, and no runtime errors occured, it just gave the wrong answers
>(i was always 0).  It wasn't immediately obvious that the modf call was to
>blame, but once I got that far checking the man page I found that modf is
>double modf(double, *double).  Changing i to double fixed the problem.
>(This error occured because a certain useless pocket reference to the C
>libraries said i should be int.  I'm glad I didn't pay anything for it,
>or I'd be even more pissed.)

It is well(?) known that C does NO type checking on arguments to subroutines,
even with appropriate include files (prototypes weren't invented yet).  But
if you are using C you really ought to use lint to add to the rudimentary
type checking in the compiler.  That still leaves lint+C with both an
inadequate type system and inadequate type checking, but in some
environments we have to live with it.  It would have caught this error.

>
>The point is, I don't care what numeric type i is.  In a dynamically typed
>language this type error would not occur.  

It seems to me it still would:  if modf returned for you an i which was a double
and the switch statement knew only how to handle int's, you would get a
runtime error because of mismatched types.  (If you allow for smarter switch
statements or implicit conversion, you've changed the comparison to one of
flexibility of the type system rather than static vs. dynamic typing.)

> In dynamically typed languages
>a lot of things that can be type errors in static languages simply *cannot*
>cause errors.  
I believe that most dynamically typed languages have more flexible type
systems than most statically typed systems, but I need convincing on the 
point above.  Separate the issue of the type system from dynamic vs. static.
Suppose you had two languages with the same type system (e.g. same set of
functions and operators accepting the same sets of types of arguments), but
one was statically typed and the other dynamically typed.  The dynamically
typed language would catch all type errors at runtime, presumably with good
diagnostics about just what variables and types and functions were involved.
The statically typed system would catch some type errors at compile time.  
The ones it did not catch would cause difficult to find errors -- at least
they do in traditional C.  The same set of errors would occur.  So I do not
understand why "a lot of things that can be type errors in static languages 
simply *cannot* cause errors [in a dynamically typed language]".

The issue of uncaught type errors is actually because the statically typed
language is insufficiently *strong*, not because it is static.  There are
three variables that get confused in these discussions:
		expressiveness of the type system
		dynamic vs. static
		strong vs. weak

>I think much of the belief in the extra safety of statically
>typed languages is based on experience with C, where uncaught type errors
>are a common and serious problem.  C is a terrible example that gives all
>of the disadvantages of static typing with very little safety in return.

C is a prime example of static weak typing (weak in the sense that not all type
errors are caught at either run or compile time); I see no reason why any
current compiler should not be strong for an ANSI-C type language, barring
language allowed loopholes (like pointer casting).  I see no reason why anyone
would develop a dynamic weak language.  Newer static languages (e.g. C++) are
strong with loopholes ("segmentation fault" with termination being as bad for
the user as "message not understood" followed by termination).
Furthermore, if you count domain errors (such as divide by zero) as type errors,
no language is completely statically typed; it may still be strong if that error
is caught and reported at run-time; out-of-range errors are sometimes uncaught 
(e.g. C), and sometimes are caught at run-time (always or switchable at 
compile time).   So we are left with
		strong dynamic languages
		strong mostly static languages

With the *same type system* these will catch the *same* errors -- and I'd
rather catch as many at compile-time as possible.  BUT,  it seems to me that
it is much easier to provide a more flexible type system in a dynamically
typed environment; languages which have appeared to date bear this out (the
presence of type loopholes in at least some static languages is a tacit
admission that the type system is not flexible enough).  And
flexibility in typing is important for reuse of code and hence for quick
prototyping.  The challenge is to provide a flexible type system in which the 
compiler can do sufficient type analysis so that (a) as many type errors are 
reported by the compiler as is feasible (b) as many type tags are optimized 
away as is possible and (c) the rest of the potential errors are dynamically 
checked.  This would give a strong expressive language with a mixture of 
static and dynamic typing.  Maybe the compiler would even give switches -t0 .. 
-t9 trading off speed of compilation vs. amount of static/dynamic checking.

David R. Cok
Eastman Kodak Company
cok@Kodak.COM


