From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: fac41,b87849933931bc93 X-Google-Attributes: gidfac41,public X-Google-Thread: 109fba,b87849933931bc93 X-Google-Attributes: gid109fba,public X-Google-Thread: 103376,b87849933931bc93 X-Google-Attributes: gid103376,public X-Google-Thread: 114809,b87849933931bc93 X-Google-Attributes: gid114809,public X-Google-Thread: 1108a1,b87849933931bc93 X-Google-Attributes: gid1108a1,public From: ok@goanna.cs.rmit.EDU.AU (Richard A. O'Keefe) Subject: Re: OO, C++, and something much better! Date: 1997/01/22 Message-ID: <5c4ab5$134$1@goanna.cs.rmit.EDU.AU> X-Deja-AN: 212499694 references: <5buodl$bci@boursy.news.erols.com> <32E2FEC7.2F7B@concentric.net> <5bvncj$gqg$1@A-abe.resnet.ucsb.edu> <32E47B4B.56D9@concentric.net> <6PI998tV3RB@herold.franken.de> organization: Comp Sci, RMIT, Melbourne, Australia newsgroups: comp.object,comp.lang.c++,comp.lang.ada,comp.lang.smalltalk,comp.lang.eiffel nntp-posting-user: ok Date: 1997-01-22T00:00:00+00:00 List-Id: jhd@herold.franken.de (Joachim Durchholz) writes: >Oh yes there is a difference. The compiler will catch all errors; the run- >time system will miss some. I have seen this argument the other way around: in a language with strong *dynamic* checking, the run time system catches all the errors that actually happen, while a static checker misses a lot of them. It simply isn't true that "the compiler will catch all errors". Or rather, it is true only if you play language games and redefine "errors" to be things that can be checked statically leaving run time attemps to apply operations outside their domains looking for another name. For example, A: array (Integer range 0 .. 1) of Integer; I: Integer; ... I := A(I); A compiler would catch I(A) as a static type error, but not the case where I is 2 at run time. To someone with a dynamic typing perspective, _both_ I(A) and A(2) are attempts to apply an operation (subscripting) to arguments outside its domain. Surely the answer is not to be dogmatic either way, but to accept that - no amount of static checking is ever going to eliminate the need for _all_ dynamic checking - dynamic checking has a run time cost; other things being equal it is better to move it to compile time - dynamic checking has a life cycle cost; other things being equal it is better to catch errors with a compiler than with testing - static checking limits expressiveness to what the language designer believed was feasible (the Ada 95 type system really is very limited, why TYPE isn't even a type!) - static checking has a life cycle cost; it _may_ pay off during a prototyping phase, for example. >In other words: I'd feel really embarrassed if the user ever saw a >"message not understood" error. Don't worry, I see enough "core dumped" messages on one system and pretty pictures of bombs on another, and my friends see "GPF" often enough, that we'd forgive you... >IMHO, bugs that can be found automatically should be found automatically. Not all languages are used by software engineers. For example, I am currently working with a language called R, based on S. It's an interactive programming language for statistics and graphics. S is well regarded by its users, If it required declarations, they wouldn't use it. (Serious number crunching is done via a type checked interface to C and Fortran. S code is normally used to decide _what_ to compute rather than _how_ to compute it.) The things a statistician does and programs with S are at least in part driven by what _today's_ data set turns out to be life. It's a very different _kind_ of life cycle. >So, dynamic typing has the disadvantage that it makes a set of compile- >time checks impossible. This is simply false. For example, the Mycroft/O'Keefe type checker for Prolog is a static type checker for Prolog. Having dynamic type checking in the underlying Prolog system in *NO* way prevents layering a good static type checker on top. In the same way, there are a number of static type checkers around for Scheme; the fact that the underlying implementation does dynamic checking in *NO* way "makes a set of compile-time checks impossible" or even particularly difficult. All it means is that the static type checker will reject some Prolog or Scheme programs that would have had no run time type errors; no limitation _compared with other static systems_ is entailed. >The only issue worth discussing is wether this >disadvantage is set off by added flexibility, or not. And the result of >the discussion may well be different depending on circumstances - e.g. how >much of the Smalltalk flexibility is actually due to the environment, not >to dynamic typing? In the case of S and R, the environment is pretty limited. It is _definitely_ the dynamic typing which make these languages attractive to their intended users. For example, a common transformation is to take slightly adjusted square roots of counts. So let's do transform.count <- function (count) sqrt(count + 0.5) Ok, now we have a function which will accept a single number, a vector, an array with any number of subscripts, a time series, one of these things with or without dimension labels, and so on, and it will "do the right thing". (Anyone who is reminded of APL ought to be.) Oh yes, and the numbers could be integers, single precision, double precision, or complex. It is not beyond human power to come up with a type system that can handle this kind of thing, assume integer <: single <: complex <: double-complex single <: double <: double-complex 0.5: single + : dimension DL array of TL where TL <: double-complex x dimension DR array of TR where TR <: double-complex -> dimension max(DL,DR) array of lub(TL,TR) sqrt : dimension D array of T where T <: double-complex -> dimension D array of lub(single, T) from which we can infer (in a Hindley-Milner sort of way) transform.count : dimension D array of T where T <: double-complex -> dimension D array of lub(T, single) except that S values may have many other attributes. The type system would be fairly complex. (The type of transform.count, for example, even if expressed as something like [D,T<:double-complex,A] -> [D,lub(T, single),A] is bigger than its code.) -- My tertiary education cost a quarter of a million in lost income (assuming close-to-minimum wage); why make students pay even more? Richard A. O'Keefe; http://www.cs.rmit.edu.au/%7Eok; RMIT Comp.Sci.