Xref: utzoo comp.lang.misc:6906 comp.object:2765 Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!magnus.acs.ohio-state.edu!tut.cis.ohio-state.edu!sei.cmu.edu!fs7.ece.cmu.edu!o.gp.cs.cmu.edu!ram From: ram+@cs.cmu.edu (Rob MacLachlan) Newsgroups: comp.lang.misc,comp.object Subject: Re: Dynamic typing -- To Have and Have Not (was Runti Message-ID: <1991Mar18.210115.21233@cs.cmu.edu> Date: 18 Mar 91 21:01:15 GMT References: <18926:Mar1422:18:5691@kramden.acf.nyu.edu> <1991Mar16.052952.10201@cs.cmu.edu> <3523:Mar1803:21:0591@kramden.acf.nyu.edu> Sender: netnews@cs.cmu.edu (USENET News Group Software) Organization: School of Computer Science, Carnegie Mellon Lines: 77 >From: brnstnd@kramden.acf.nyu.edu (Dan Bernstein) >Subject: Re: Dynamic typing -- To Have and Have Not (was Runti >Date: 18 Mar 91 03:21:05 GMT > >I can't afford to use Lisp either: I don't find its slight advantages in >expressiveness to outweigh its slowness for all but the simplest >programs. > If you are writing programs that can't afford a to run 50% to 100% longer than a tense C implementation, then don't use Lisp. The advantage of Lisp (and of object-oriented programming) is not in efficiency, but in ease of evolving solutions to poorly understood problems. I agree that compile time type checking is a good thing -- the Python compiler that I wrote for CMU Common Lisp does compile-time type checking wherever possible. If you want to, you can write statically type-checked programs in Common Lisp. This will get a compile-time type warning in CMU CL: (defvar *var* '(a b c)) (declaim (list *var*)) (defun foo () (+ *var* 13)) As I see it, the main difference between CL and a language such as C is that CL knows that it doesn't always know the types of objects, whereas C pretends that it does. I think that dynamic typing is especially valuable in an object-oriented programming system, since OO programs intensively manipulate references to mutable objects. It is very difficult to do static type checking in such an environment. Determining the power of the type system is a language design decision: -- The more of the language semantics you bring into the type system, the more complex inferences you can do at compile time. -- It is impossible to bring all the language semantics into the type system, since the only way to really find out what a program is going to do is to run it (the halting problem, etc.) This means that: -- More powerful type systems offer more opportunities for optimization, but are also harder for compilers to understand. -- In any language, some programming errors can only be detected at run time. > [...] static typing appears to greatly reduce >debugging time without hurting speed or space or effort for the vast >majority of projects. Well, you say it's so, and I say it ain't... Static type checking detects superficial errors; errors that would be detected if you tested that branch in the code just once. Such bugs may be common, but fixing them is quite easy in any language. Here is a concrete example of a programming problem that exemplifies what programmers in any OO language spend most of their *time* debugging: (do ((current foo (foo-next current))) ((eq (foo-a current) 'yow!) current)) We search down a linked list of FOOs for a FOO whose A is YOW!. If for some reason, it isn't there, then we fly off the end of the list (and get a run-time error.) This is a nasty bug, because the problem isn't determining *that* we flew off the end of the list, the problem is determining *why* YOW! wasn't in the list. And the only relevant tool that current languages offer is run-time assertions: (assert (find-in #'foo-next 'yow! foo :key #'foo-a))) Of course, you can do run-time consistency checks in any language. The point is that for finding the hard bugs, that is what you end up doing in any language. >> Do your programs ever dump core? That's a run-time error check, just not a >> very graceful one. > >Yes, and one which could quite often have been prevented by stronger >compile-time checks. I do seem some potential in powerful type-inferencing systems such as in ML, but even in these languages, run-time assertions are important. Rob MacLachlan (ram@cs.cmu.edu)