Path: utzoo!attcan!uunet!crdgw1!uakari.primate.wisc.edu!sdd.hp.com!zaphod.mps.ohio-state.edu!julius.cs.uiuc.edu!apple!agate!shelby!neon!craig From: craig@Neon.Stanford.EDU (Craig D. Chambers) Newsgroups: comp.object Subject: Re: Do we really need types in OOPL's? Message-ID: <1990Oct19.220747.5536@Neon.Stanford.EDU> Date: 19 Oct 90 22:07:47 GMT References: <1990Oct9.190813.23402@ux1.cso.uiuc.edu> <2444@runxtsa.runx.oz.au> <1990Oct19.180646.8649@ux1.cso.uiuc.edu> Organization: Stanford University Lines: 93 In article <1990Oct19.180646.8649@ux1.cso.uiuc.edu> render@cs.uiuc.edu (Hal Render) writes: >In article <2444@runxtsa.runx.oz.au> timm@runxtsa.runx.oz.au (Tim Menzies) writes: > [an article about how Smalltalk's lack of strong-typing hasn't been > a detriment to his work] > >Assuming that any software you write is thoroughly tested, most >type errors that would be caught at compilation can be caught during >testing. I think that this is the reason that strong typing may >not be absolutely necessary. However, any error that can be caught >by the compiler is one less that a human has to catch, and so I >personally like having type-checking as part of a programming language. You're assuming that you can add static type checking to a language with little cost (just a few extra declarations). This is not true in existing statically-typed languages. A statically-checkable type system imposes restrictions on the kinds of programs that you can write. If the static type system isn't smart enough to guarantee that you aren't possibly going to do anything wrong, then it will complain and prevent you from running your program. Static type systems and checkers make conservative approximations about programs, and so lose information that an "ideal type checker" would have used to show that the program type checks. In many situations, the approximations aren't far off of reality, but in others the approximations lose too much information. Consider the perform: primitives in Smalltalk. These are very hard to type-check without doing analysis of the possible *values* of the run-time selector. No static type system I know of can statically type check a perform: primitive in any but the most trivial cases. The user interface in Smalltalk uses perform: all the time to execute arbitrary user actions when a menu entry is selected. Become: is another hard-to-type-check primitive in Smalltalk. Another case in Smalltalk is the implementation of growable arrays (I think; some collection in Smalltalk has this problem). The representation of a growable array is a vector of indexable fields, a lower bound, and an upper bound (or maybe a length, I don't remember). The elements of the growable array are in the fields indexed between the lower bound and the upper bound; the contents of the extra padding fields are nil. This poses problems for a static type checker, since the best static type systems that I've seen will treat the type of the indexable fields as "T | Nil" (where "T" is the parameterized type of the elements of the growable array). So fetches out of the indexed fields return objects that the type checker thinks are of type "T | Nil", while the programmer knows that they really should be just "T". >Another potential benefit of strong typing is in allowing >compilers to produce more efficient code. Although I haven't >read much on the issue, I have heard that one of the reasons that >Ralph Johnson's Typed Smalltalk compiler may turn out to be quite usefule >is that the type checking may allow the compierl to optimize method >look-up. Anything that can improve the speed of Smalltalk code will >help it to gain wider acceptance among project managers which in >turn would mean that more programmers could use Smalltalk instead of >nastier, grundgier languages (pick one). This would be A Good Thing. Typed Smalltalk's type system can't handle the above cases any better than any other type system. In fact, Typed Smalltalk includes a type cast operation to force "T | Nil" to "T" where the programmer tells the compiler he knows what he's doing; I don't know how Typed Smalltalk type-checks perform:'s and become:'s. And I disagree that type declarations are required to get good speed. For one thing, good type systems specify *interface*, not *representation*, to maximize generality and reusability. But optimization like compile-time message lookup require representation information. And techniques exist to infer the representation of objects from code with no type declarations, like customization, type prediction, type analysis, and splitting. These techniques are used in the compiler for Self, a dynamically-typed o-o language much like Smalltalk, except that no cheating is allowed for common messages like ifTrue, whileTrue, and +, and instance, class, and global variables are all accessed using message passing. The performance of Self is around 50% to 75% of optimized C for small benchmarks translated from C, even without type declarations, so the techniques for inferring the representation of objects must work pretty well, at least for integers and arrays (the data types manipulated in the benchmarks). The performance of Typed Smalltalk is about the same as Self for some very small benchmarks like sumTo: (around 2.5 times slower than optimized C), even though Typed Smalltalk has declared all the variables to be SmallIntegers and generic arithmetic support has been disabled (i.e. no overflow checks or type tests for arithmetic). I agree wholeheartedly that anything that convinces programmers to use nicer languages like Smalltalk (or, even better, Self) would be a Great Thing, and better run-time performance is certainly one important factor. But I believe that static type declarations are not that important for good run-time performance, especially if the type declarations specify interface rather than representation; good compiler techniques are much more important, and fortunately they now exist. -- Craig Chambers