eberard@ajpo.sei.cmu.edu (Edward Berard) (01/05/90)
Folks, I recently posted a large message to comp.object on the evaluation of object-oriented programming languages. I have received a number of responses. I would be interested in getting your reaction to the following quotes from one of respondees: >> object-oriented programming. Smalltalk has, in effect, no >> types, but there are typed extensions to Smalltalk, e.g., > > Again, CL and Smalltalk have *run-time* types - restrictions on > the use of *objects* during program *execution*. Languages such > as Ada have *compile-time* types - restrictions on the use of > *identifiers* during program *compilation.* [...] > > More accurately, run-time typing places the burden on the run-time > system, whereas compile-time typing places the burden on the > compiler *and* the programmer (who must provide explicit type > declarations and obey them at all times during program > development). I would ask again what solid *experimental* > evidence anyone has to show that compile-time typing actually > results in programs more reliable than those possible with > run-time typing, *in the presence of the requirements evolution > that is present in any large, complex software project*. Are there any references documenting the benefits of strong vs. weak typing? What are your reactions to the definitions given? -- Ed Berard (301) 353-9652 P.S.: For those that don't know, "CL" stands for Common Lisp.
david@cs.washington.edu (David Callahan) (01/05/90)
>> More accurately, run-time typing places the burden on the run-time >> system, whereas compile-time typing places the burden on the >> compiler *and* the programmer (who must provide explicit type >> declarations and obey them at all times during program >> development). This statement is misleading. Many research languages perform compile-time type checking based on type-inference algorithms and allowing a powerful, polymorphic type system. While research work indicates that type-inference at reasonable generality is undecidable, it does not seem to be a tremendous problem in practice. -- David Callahan (david@tera.com, david@june.cs.washington.edu,david@rice.edu) Tera Computer Co. 400 North 34th Street Seattle WA, 98103
reino@cs.eur.nl (Reino de Boer) (01/05/90)
eberard@ajpo.sei.cmu.edu (Edward Berard) writes: >I would be interested in getting your reaction to the >following quotes from one of respondees: >>> object-oriented programming. Smalltalk has, in effect, no >>> types, but there are typed extensions to Smalltalk, e.g., >> >> Again, CL and Smalltalk have *run-time* types - restrictions on >> the use of *objects* during program *execution*. Languages such >> as Ada have *compile-time* types - restrictions on the use of >> *identifiers* during program *compilation.* I tend to agree with `>>>' that Smalltalk has no types. The feeling of run-time types is actually the `not being able to respond to certain messages'. >Are there any references documenting the benefits of strong vs. weak >typing? What are your reactions to the definitions given? My reaction: I think languages like Miranda have shown us that the effects of run-time type-checking can for a very large part be accomplished by compile-time evaluation of possible types. Although something can be said in favor of the statement all interpreters (CL, Smalltalk, etc.) by definition do only run-time checking (not being able to compile at all). P.S. Thank you for your overview of Object-Oriented Design. Reino -- Reino R. A. de Boer Erasmus University Rotterdam ( Informatica ) e-mail: reino@cs.eur.nl
nick@lfcs.ed.ac.uk (Nick Rothwell) (01/05/90)
In article <641@ajpo.sei.cmu.edu>, eberard@ajpo (Edward Berard) writes: I would be interested in getting your reaction to the >following quotes from one of respondees: >> More accurately, run-time typing places the burden on the run-time >> system, whereas compile-time typing places the burden on the >> compiler *and* the programmer (who must provide explicit type ^^^^^^^^^^^^... >> declarations and obey them at all times during program >> development). This is false for a polymorphic type system. >> I would ask again what solid *experimental* >> evidence anyone has to show that compile-time typing actually >> results in programs more reliable than those possible with >> run-time typing, *in the presence of the requirements evolution >> that is present in any large, complex software project*. Do you mean "practical experience"? I wrote 8000 lines in ML, and hand-translated to 20000 lines of C, in 4 months, resulting in a reliable piece of software. I don't know how to quantify that in any objective way, though. I suggest that compile-time typing serves the same purpose as module interfaces: it lets you decide what you want different parts of a project to see, and what operations you want to provide (I'm thinking of a parameterised, abstract type system here). Nick. -- Nick Rothwell, Laboratory for Foundations of Computer Science, Edinburgh. nick@lfcs.ed.ac.uk <Atlantic Ocean>!mcvax!ukc!lfcs!nick ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ "...all these moments... will be lost in time... like tears in rain."
gudeman@cs.arizona.edu (David Gudeman) (01/06/90)
[anonymous quotes...] >>> object-oriented programming. Smalltalk has, in effect, no >>> types, but there are typed extensions to Smalltalk, e.g., >> >> Again, CL and Smalltalk have *run-time* types - restrictions on >> the use of *objects* during program *execution*. Languages such >> as Ada have *compile-time* types - restrictions on the use of >> *identifiers* during program *compilation.* I think there is some confusion here between "having types" and "being typed". In particular, it is possible for a language to have types (as Smalltalk and CL do) and still to be untyped (as Smalltalk and CL are). These languages are not "weakly typed", they are "untyped". All languages "have types", in the sense that values in the language can be categorized (even if there is only one category). CL has the types "integer", "real", "string", "cons", etc. A language is said to "be typed" if the identifiers of the language (variable, function names, etc.) are constrained to represent values of specific types. The difference between strong and weak typing involves how much you can say about the types of values that the identifiers can take. Here are examples in C (a typed language) and Icon (an untyped language with a syntactic resemblance to C): int add(a,b) int a,b; {return a + b;} /* C */ procedure add(a,b) return a + b end # Icon The C procedure is typed because the identifiers "a" and "b" are restricted to represent values of type int, and the identifier "add" is restricted to represent a value of type (int X int) -> int (actually the type restriction "add" is a rather trivial one since it is a constant). In the Icon procedure, "a" and "b" may have values of any type: int, real, or even procedure. If one of both of them is not numeric (or convertible to numeric) then a run-time error will occur when you try to add them. Likewise, the identifier "add" in the Icon program is untyped. It may take on a value of a different type (even int) during the execution of the program. -- David Gudeman Department of Computer Science The University of Arizona gudeman@cs.arizona.edu Tucson, AZ 85721 noao!arizona!gudeman
lgm@cbnewsc.ATT.COM (lawrence.g.mayka) (01/06/90)
In article <10287@june.cs.washington.edu> david@june.cs.washington.edu (David Callahan) writes: >>> More accurately, run-time typing places the burden on the run-time >>> system, whereas compile-time typing places the burden on the >>> compiler *and* the programmer (who must provide explicit type >>> declarations and obey them at all times during program >>> development). > >This statement is misleading. Many research languages perform >compile-time type checking based on type-inference algorithms and >allowing a powerful, polymorphic type system. While research work >indicates that type-inference at reasonable generality is undecidable, >it does not seem to be a tremendous problem in practice. Consider a dynamically constructed list of objects such that: a) The types of the elements have no necessary relation - i.e., the list is totally heterogeneous; b) The types of the elements are not knowable at compile time, but are each knowable at run time - i.e., a TYPE-OF or CLASS-OF function is available; c) The length of the list is not knowable at compile time, but is knowable at run time. Programs in run-time typed languages make ubiquitous use of such lists. If one cannot create and manipulate such lists easily and efficiently in the research languages you describe, I suggest that there is indeed a "problem in practice." The distinction between compile-time typing and run-time typing remains a valid one. Moreover, a programming environment which requires specification of all program parts in advance of compilation (e.g., in order to perform type inferencing across function calls) faces essentially the problems of compile-time typing: hindrance of incremental system development and obstruction of smooth system evolution. Type inferencing within a function, or on programmer request (e.g., via optional declarations), is of course a welcome optional optimization. Lawrence G. Mayka AT&T Bell Laboratories lgm@ihlpf.att.com Standard disclaimer.
lgm@cbnewsc.ATT.COM (lawrence.g.mayka) (01/06/90)
In article <1990Jan5.084746.17836@cs.eur.nl> reino@cs.eur.nl (Reino de Boer) writes: >compile-time evaluation of possible types. Although something can be >said in favor of the statement > all interpreters (CL, Smalltalk, etc.) by definition do only > run-time checking (not being able to compile at all). Common Lisp programs are typically compiled into native machine instructions. For example, one typical implementation on the SPARC architecture compiles the following function (defun add (x y) (+ x y) ) into exactly 11 machine instructions. Such a function properly computes the sum of any two numbers - integers of any size, floating-point, rational, or complex. (Only 5 instructions are executed if each argument happens to be an integer that fits into a single machine word.) If one annotates this definition with optional type declarations thus: (defun add (x y) (declare (fixnum x y)) (the fixnum (+ x y)) ) the compiler emits exactly 4 machine instructions. If this latter function is passed arguments of unexpected types - e.g., rational numbers 4/5 and 7/8 - the run-time system traps the attempt and asks the user if it should proceed with the addition anyway. This exception handling behavior can of course be overridden by the programmer.) An interpreter is usually also available but most CL programmers use it primarily to execute top-level environment commands such as ED, COMPILE-FILE, LOAD, TRACE, DESCRIBE, INSPECT, and DISASSEMBLE. Lawrence G. Mayka AT&T Bell Laboratories lgm@ihlpf.att.com Standard disclaimer.
rh@ecs.soton.ac.uk (R Harrison) (01/10/90)
In article <1990Jan5.084746.17836@cs.eur.nl> reino@cs.eur.nl (Reino de Boer) writes: >eberard@ajpo.sei.cmu.edu (Edward Berard) writes: > >>Are there any references documenting the benefits of strong vs. weak >>typing? The advantages of strong typing have been recognised for some time - consider, for example, Gries and Gehani ("Some ideas on data type in high level languages, CACM 20, 1977, pp.414-420), in which the case for controlled polymorphic programming is discussed. Rachel Harrison rh@uk.ac.soton.ecs Department of Electronics and Computer Science, University of Southampton, Southampton SO9 5NH, UK Tel. (0703) 593055 International 44 703 593055 Fax 0703 593045 International Fax 44 703 593045
reino@cs.eur.nl (Reino de Boer) (01/12/90)
lgm@cbnewsc.ATT.COM (lawrence.g.mayka) writes: >In article <1990Jan5.084746.17836@cs.eur.nl> reino@cs.eur.nl (Reino de Boer) writes: >> all interpreters (CL, Smalltalk, etc.) by definition do only >> run-time checking (not being able to compile at all). >Common Lisp programs are typically compiled into native machine >instructions. >An interpreter is usually also available but most CL programmers >use it primarily to execute top-level environment commands such as >ED, COMPILE-FILE, LOAD, TRACE, DESCRIBE, INSPECT, and DISASSEMBLE. The point I was trying to make, is that an interpreter can BY DEFINITION do no compile-time checking. Some `compilers' allow a form of run-time checking because they include a run-time interpreter in the compiled code. I would like to classify these compilers under interpreters. Some `interpreters' allow a form of compile-time checking because they interpret some kind of internal code. Depending on the semantics of the internal code, these could be classified under compilers. The only reasonable way for a compiler to allow run-time type checking would be to include type-checking code in the compiled code. However, there is more than one issue being discussed here: 1. What would be reasonable definitions for o run-time type checking; o compile-time type checking. 2. Given a solution to (1), what are the advantages and disadvantages of both kinds of type-checking. 3. Given an answer to (2), o what would be the best way to let a programmer influence the checking mechanism (e.g., type declarations as in Pascal, or polymorphic typing as in Miranda) o does type checking have to be `strong' or `weak' (and what would be suitable definitions for `strong' and `weak'). Example: Strong type checking in Pascal would give the programmer the opportunity to get a compiler error on the following: program wrong( output ); type distance = real; money = real; var d : distance; m : money; begin d := 5.5; m := 10.0; writeln( d + m : 10 : 2 ) end. Any comments? -- Reino -- Reino R. A. de Boer Erasmus University Rotterdam ( Informatica ) e-mail: reino@cs.eur.nl
franka@mentor.com (Frank A. Adrian) (01/13/90)
In article <2197@ecs.soton.ac.uk> rh@landin (R Harrison) writes: >In article <1990Jan5.084746.17836@cs.eur.nl> reino@cs.eur.nl (Reino de Boer) writes: >>eberard@ajpo.sei.cmu.edu (Edward Berard) writes: >> >>>Are there any references documenting the benefits of strong vs. weak >>>typing? > >The advantages of strong typing have been recognised for some time >- consider, for example, Gries and Gehani ("Some ideas on data type >in high level languages, CACM 20, 1977, pp.414-420), in which the case >for controlled polymorphic programming is discussed. > And the disadvantages of strong typing during early development has also been recognized for some time - consider, for example, Sandewall ("Programming in an Interactive Environment: The LISP Experience", Computing Surveys, 1978, pp. 35-72), where we find the quote (p. 38): "The contents and use of declarations is one of the important issues that one wants to experiment with in a research system, and therefore should not be frozen in the system kernel. In- stead the internal form of programs should be declaration free, and one of the services of the developing programming system should be to account for declarations as input by the user." I take Sandewall's view. Maybe the systems that you work on are so well specified or the concepts you deal with in your programs are so well un- derstood, even in the early stages, that you have no need of "playing with the program". I don't. Nobody I know does. I have no objections to having a well specified type structure in a delivered product (and in fact see see the necessity for one at that stage both for correctness and efficiency), but hamstringing languages to REQUIRE it in ALL stages of development seems to be a bit of overkill. We may ask a somewhat cynical question as to if the difficulty of setting up and changing type hierarchies in the strongly-typed languages leads to programs which: a) are "correct" with respect to the initial specification, but b) have not explored the possible type configuration space suf- ficiently to have a maintainable type structure, so c) significant changes to these strongly-typed structural behemoths are next to impossible. I guess the bottom line is that, at least for me (and, I believe, for many others), the case for having less strongly typed languages is far from closed. -- Frank A. Adrian Mentor Graphics, Inc. franka@mntgfx.com
lgm@cbnewsc.ATT.COM (lawrence.g.mayka) (01/14/90)
In article <2197@ecs.soton.ac.uk> rh@landin (R Harrison) writes: >The advantages of strong typing have been recognised for some time >- consider, for example, Gries and Gehani ("Some ideas on data type >in high level languages, CACM 20, 1977, pp.414-420), in which the case >for controlled polymorphic programming is discussed. Gries and Gehani bring up the alternative of run-time typed languages (the authors call them "typeless") in a single paragraph at the end of their article. Interestingly, they mention as examples APL and Snobol but omit Lisp, which I suspect was the most widely used of the three even in those days. (The Interlisp and MIT Lisp machine programming environments already existed in 1977, though they were perhaps not yet well known.) The authors reject such languages for three reasons. First, Gries and Gehani complain of interpretive implementations. This accusation no longer applies - not to Common Lisp, anyway. Second, the authors mention the unparsability of APL. This difficulty, for which Gries and Gehani give an example, does not apply to other run-time typed languages. Indeed, the accusation today is much more applicable in the opposite direction: Common Lisp is particularly easy to parse, whereas C++ is practically unparsable. (Send me mail for a particularly nasty example.) The authors' third reason for rejecting run-time typing is that "one cannot tell just by looking at a procedure just what it does; it will depend too heavily on the inputs to that procedure." This objection is equally applicable, of course, to the authors' own proposal of parameterized types. More ironic is the fact that many popular language abstractions, including object-oriented programming itself, are equally vulnerable to this same accusation. And of course, Gries and Gehani give no concrete evidence of the superiority of their preferences. Indeed, their primary criteria - listed as readability, understandability, provability of correctness, and run-time efficiency - apparently do not include productivity, extensibility, or evolvability. Lawrence G. Mayka AT&T Bell Laboratories lgm@ihlpf.att.com Standard disclaimer.
sommar@enea.se (Erland Sommarskog) (01/14/90)
Reino de Boer (reino@cs.eur.nl) writes: > Example: > Strong type checking in Pascal would give the programmer the > opportunity to get a compiler error on the following: > program wrong( output ); > type distance = real; > money = real; > var d : distance; > m : money; > begin d := 5.5; m := 10.0; writeln( d + m : 10 : 2 ) end. WOULD give, yes, if Pascal had been a strongly typed language. Alas, the typing in Pascal is fairly weak, so there is no possibility for a programmer to enforce distinction between two entities that have no connection to each other than being represented by a real or integer number. But of course there are languages which give you this possibility, but I doubt that Wirth designed any of them. -- Erland Sommarskog - ENEA Data, Stockholm - sommar@enea.se Unix is a virus.
lgm@cbnewsc.ATT.COM (lawrence.g.mayka) (01/15/90)
In article <1990Jan13.155115.4809@mentor.com> franka@mntgfx.UUCP (Frank A. Adrian) writes: >of development seems to be a bit of overkill. We may ask a somewhat >cynical question as to if the difficulty of setting up and changing type >hierarchies in the strongly-typed languages leads to programs which: > > a) are "correct" with respect to the initial specification, but > b) have not explored the possible type configuration space suf- > ficiently to have a maintainable type structure, so > c) significant changes to these strongly-typed structural behemoths > are next to impossible. For this reason I submit that run-time typing is particularly appropriate for large software systems that must evolve continuously over a long lifecycle in response to unforeseen customer needs - e.g., feature-rich telecommunications switching systems. Lawrence G. Mayka AT&T Bell Laboratories lgm@ihlpf.att.com Standard disclaimer.
nick@lfcs.ed.ac.uk (Nick Rothwell) (01/16/90)
In article <12843@cbnewsc.ATT.COM>, lgm@cbnewsc (lawrence.g.mayka) writes: >For this reason I submit that run-time typing is particularly >appropriate for large software systems that must evolve >continuously over a long lifecycle in response to unforeseen >customer needs - e.g., feature-rich telecommunications switching >systems. I see no reason why you can't do that kind of thing with a static type system, as long as it's flexible enough. If you have polymorphism, type abstraction, parameterised types and a decent type-secure module system then the abstraction mechanisms limit the amount of dependency between modules, so that changes are as localised as possible. Even for the inevitable global changes, if you trust the type system, then you can tend to make the changes to the support modules which provide the basic types, and let any changes to the types and sharing constraints propagate through. The work is done when the typechecker accepts the whole system once again. > Lawrence G. Mayka Nick. -- Nick Rothwell, Laboratory for Foundations of Computer Science, Edinburgh. nick@lfcs.ed.ac.uk <Atlantic Ocean>!mcvax!ukc!lfcs!nick ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ "...all these moments... will be lost in time... like tears in rain."
jeff@aiai.ed.ac.uk (Jeff Dalton) (02/23/90)
In article <12820@cbnewsc.ATT.COM> lgm@cbnewsc.ATT.COM (lawrence.g.mayka,ihp,) writes: >Gries and Gehani bring up the alternative of run-time typed >languages (the authors call them "typeless") in a single paragraph >at the end of their article. Interestingly, they mention as >examples APL and Snobol but omit Lisp, which I suspect was the >most widely used of the three even in those days. (The Interlisp >and MIT Lisp machine programming environments already existed in >1977, though they were perhaps not yet well known.) The authors >reject such languages for three reasons. First, Gries and Gehani >complain of interpretive implementations. This accusation no >longer applies - not to Common Lisp, anyway. Lisp, and Lisp compilers, have been around since at least the early 60's. It's strange how some people think certain languages are inherently interpreted even though there is evidence to the contrary for anyone who cares to look. For example, the Dartmouth implementations of Basic were always compilers. >Second, the authors mention the unparsability of APL. As if this was because it was "typeless". >The authors' third reason for rejecting run-time typing is that >"one cannot tell just by looking at a procedure just what it does; >it will depend too heavily on the inputs to that procedure." I wonder how many procedures they actually looked at. In many cases, it's clear what sorts of objects are involved, either because there are explicit tests or because type-specific procedures are called. Of course, being sure that the argument types will really be what they should be is another matter. Besides, knowing the types of the parameters doesn't tell you what the procedure does. It helps in some cases, but hardly matters at all in others.