Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!samsung!uunet!odi!dlw From: dlw@odi.com (Dan Weinreb) Newsgroups: comp.object Subject: Re: Type-safe does not mean safe Message-ID: <1990Oct5.184609.7942@odi.com> Date: 5 Oct 90 18:46:09 GMT References: <3832@osc.COM> <1990Oct2.170910.4805@eua.ericsson.se> <1990Oct5.010703.16019@Neon.Stanford.EDU> Reply-To: dlw@odi.com Organization: Object Design, Inc. Lines: 64 In-Reply-To: craig@Neon.Stanford.EDU's message of 5 Oct 90 01:07:03 GMT In article <1990Oct5.010703.16019@Neon.Stanford.EDU> craig@Neon.Stanford.EDU (Craig D. Chambers) writes: Most dynamically-typed languages (i.e. languages that do not type check programs statically but instead defer any necessary type checks until run-time) are strongly typed (e.g. Lisp (at least interpreted versions), Smalltalk, Self), since the run-time system ensures that only legal (type safe) operations are applied to objects/values. By the way, just to throw another joker into the conversation (this is a digression from the main conversation about the meaning of types): When we talk about a language system that "ensures that only legal operations are applied to objects/values", I'd like to point out that there are other legality questions besides ones having to do with types. In nearly every implementation of Pascal, Fortran, C, and C++ that I know about, if you make an array of 7 elements and store a value into the 10th element of the array, execution of the program will happily complete the operation, almost certainly clobbering random unrelated variables and/or objects, creating a bug that is relatively hard to find. (I know that there are exceptional implementations, such as Sabre C; this lack of checking is not a property of the language per se, but of most implementations of the language.) In most interpreted Lisp implementations, in compiled Lisp implementations running on Lisp machines (Symbolics, at least, but I think all the others too), and in Smalltalk-80 implementations based on the ParcPlace "virtual machine" implementation (and probably other Smalltalk implementations too), such an error would be caught at runtime. (In compiled Lisps on conventional architecures, often this runtime checking is not done -- sometimes it depends on the value of the "declare optimize" flag, etc. -- again, it's a property of the implementation, not the language itself.) The same goes for languages with dynamic memory allocation and freeing, such as C, C++, and PL/I (and probably some Pascal dialects): in nearly every implementation, it is possible for a program to free memory while there are still outstanding pointers to that memory, and then use the pointers without any detection of error, leading to incorrect results or errors signalled way down the road, making the bug hard to find. This doesn't happen in Lisp and Smalltalk, which use automatic memory deallocation. Some people on this mailing list have adamantly repeated to all of us, many times, without fear of contraction, that static typing (typing of variables, checking at compile time) is *essential* for the construction of large programs. However, they don't seem to think that checking for array-index-out-of-bounds or illegal-memory-reuse are particularly important. They also appear to ignore the fact that lots of very large, complex programs have been developed, debugged, and sold to users in languages that do not have static checking. I have spent years developing commercial software products with both kinds of language systems, and I assure you that it is quite possible to do large-scale program development in either kind of language system. Both static type checking and runtime array/memory checking are helpful things to have, and the absence of either has certainly caused me grief at various times. My experience is that neither is essential but both are desirable. On the whole, I feel that the importance of static type checking is overemphasized; it's just one of many kinds of automatic checking that aid in program development and debugging.