mwm@cuuxb.UUCP (01/16/87)
In article <147@m10ux.UUCP> mnc@m10ux.UUCP writes: > This leaves me with two unanswered questions: > >(1) What is the difference (other than a rather contrived, anthropomorphic > view of the relationship between functions and values), between O-O > programming and the ten (?) year old theory and practice called "abstract > data types"? The fundamental belief with technical importance in > both methods (with which I completely agree) is that pieces of programs > should be divided into chunks that have a precisely documented interaction > with other chunks, but the internals of which are completely unknown (or > irrelevant to) other chunks. Put more concisely, "separate WHAT it does, > from HOW it does it, so that the HOW can be changed without affecting the > WHAT". Isn't O-O programming simply a special case of, i.e. one particular > method for achieving, abstract data types? It seems to lie completely > under the definition of an abstract data type as a collection of types > and functions on those types, together with the notion that we can have > multiple objects of the abstract data type. A.D.T. programming consists of defining some abstract data type, which can have some set of operations performed on it -- the set of operations and what they do defines the A.D.T. O.O. programming consists of definining some objects, which will respond to having certain messages sent to them -- the set of messages and what the object does with them defines the object. So the difference is mainly that of sending a message to an object that does the work itself, versus performing an operation upon an A.D.T. The analogy is a good one. The advantage/disadvantage to the O.O. languages is that they force you to use this Object/Message paradign all of the time. The ADT programming style is usually a method of using a particular language, which does not enforce its use. >(2) Why is it so hard for O-O programming advocates to explain the advantages > of their programming methodology without slipping into obscure, specialized > O-O jargon, or invoking the religious argument, "well you can't under- > stand why it is better until you've done a large amount of O-O programming > yourself"? Because other paradigns like ADTs don't present the options that OO programming does, like a formal way of describing general sets versus sets of integers where general sets allow operations like add( element , set ) ismember( element , set ) delete( element , set ) union( set1, set2 ) etc. and integer sets have all of those but also sum( set ) This sort of thing is easily described with things like "inheritance" in object oriented programming ( integer sets are in some sense a "descendant" of general sets, and therefore "inherit" the basic operations that general sets allow, etc.) >Michael Condict {ihnp4|vax135}!m10ux!mnc -- Marc Mengel ...!ihnp4!cuuxb!mwm
gvcormack@watmum.UUCP (01/17/87)
Object-oriented programming is a religion that is currently in vogue. It adds little to the original class ideas of Simula 67, and the abstract data type ideas of Clu (which was inspired by Simula 67). Calling a procedure call a message, and an access procedure a method is just arcane. Really the only thing that Smalltalk and its imitators add is dynamic procedure binding and dynamic type checking, which I regard as highly undesirable. -- Gordon V. Cormack CS Dept, University of Waterloo, Canada N2L 3G1 gvcormack@mum.waterloo { .CSNET or .CDN } gvcormack@water { UUCP or BITNET }
barmar@mit-eddie.UUCP (01/17/87)
In article <1023@cuuxb.UUCP> mwm@cuuxb.UUCP (Marc W. Mengel) writes: > The advantage/disadvantage to the O.O. languages is that they force > you to use this Object/Message paradign all of the time. The ADT > programming style is usually a method of using a particular language, > which does not enforce its use. This assumes the language allows ONLY o-o programming, as is the case in Smalltalk. In other cases, o-o programming is an option. For example, Flavors is an object-oriented facility within a number of Lisp dialects; Lisp itself isn't o-o, but if you want to do o-o programming within such dialects you can use Flavors. Another error you make is the assumption that object-oriented programming implies message sending. Common Loops and Symbolics's New Flavors use generic function calls instead of message sending, but they are still object oriented. -- Barry Margolin ARPA: barmar@MIT-Multics UUCP: ..!genrad!mit-eddie!barmar
lsr@apple.UUCP (Larry Rosenstein) (01/21/87)
In article <776@watmum.UUCP> gvcormack@watmum.UUCP (Gordon V. Cormack) writes: >Object-oriented programming is a religion that is currently in vogue. >It adds little to the original class ideas of Simula 67, and the >abstract data type ideas of Clu (which was inspired by Simula 67). > >Calling a procedure call a message, and an access procedure a method >is just arcane. Really the only thing that Smalltalk and its imitators >add is dynamic procedure binding and dynamic type checking, which I >regard as highly undesirable. >-- The difference comes in how easily you can make changes to your program. Consider writing a graphics application that deals with shapes (a la MacDraw). In Object Pascal (or C++ or Smalltalk) you would define an abstract Shape class, which defined the interface (protocol) for all kinds of shapes. In addition there would be Rectangle, Circle, etc. classes that inherited from Shape. Your application would manipulate shapes using the methods defined by the abstract Shape class. For example, you could create a list of Shape objects and run down the list drawing each shape. (In Smalltalk terminology you would send each Shape object a Draw message.) It would be very easy to define a new kind of Shape that provides the same interface and add it to the system; you simply define a new subclass of Shape. The graphics application itself would not have to be changed; it would be able to send messages to the new object type. In Clu, you would define a Shape data type (a cluster). The graphics application would again deal with Shape objects, without knowing about their implementation. To draw all the shapes you would interate through the list and call Shape$Draw on each shape. One difference from Object Pascal et al is that you would not define Rectangle and Circle data types. If you write code that deals with Shapes, it cannot also deal with Rectangles. (You could not use parameterized modules because they require specifying the type parameter as a constant. For example, you could define a List data type that is parameterized on the type of the data is contains. You could not, however, mix different kinds of data in the same list.) Instead, you would embed in the implementation of Shape, code to handle each of the kinds of shapes. Externally, users of Shape would not have to know whether a particular Shape was a Rectangle or Circle, but the implementation would. If you wanted to add a new kind of shape you would have to modify the implementation of Shape and recompile that module. The rest of the application would not have to change. This is different than the first example, because adding a new kind of Shape does not require changing the Shape class at all. The only code that needs to be compiled is the code that implements the new kind of shape. It is not necessary to have the sources to anything else in the system. The ability to reuse software is not limited to languages that are interpreted and have no type checking (i.e., Smalltalk). The same thing can be achieves with languages such as C++ and Object Pascal that are compiled and have type checking. -- Larry Rosenstein Object Specialist Apple Computer AppleLink: Rosenstein1 UUCP: {sun, voder, nsc, mtxinu, dual}!apple!lsr CSNET: lsr@Apple.CSNET
rentsch@unc.UUCP (Tim Rentsch) (01/21/87)
In article <776@watmum.UUCP> gvcormack@watmum.UUCP (Gordon V. Cormack) writes: > Object-oriented programming is a religion that is currently in vogue. > It adds little to the original class ideas of Simula 67, and the > abstract data type ideas of Clu (which was inspired by Simula 67). > > Really the only thing that Smalltalk and its imitators > add is dynamic procedure binding and dynamic type checking, which I > regard as highly undesirable. Be careful not to confuse the two! Runtime binding need not require "runtime type checking" (not exactly type checking, since there are no explicit checks), and in fact can be staticly checked so that "message not understood" errors cannot occur. Dynamic binding yields considerable advantages over Simula, including more polymorphic procedures and incremental compilation. (Those of you out there who have used Smalltalk and/or Lisp systems know what I'm talking about.) Basically, the only reason *not* to have dynamic binding is the belief that "it costs too much". With all the work that has been (successfully) done at making that fast (method caches, class guessing, etc.) I hope we have put THAT myth to bed. Method lookup consumes not very much (I remember it as 10%) of Smalltalk execution time. 10% is a very small price to pay for the benefits of being able to recompile and relink any procedure into a running system (~1.5 MB source code) in only a few seconds! I for one am tired of systems where the only way to produce a new version is to "compile and link overnight". Above all I want my computer systems to be responsive. If some people find that undesireable... -- well, to each his own. cheers, Tim
ark@alice.UUCP (01/22/87)
In article <672@unc.unc.UUCP>, rentsch@unc.UUCP writes: > Dynamic binding yields considerable advantages over Simula, > including more polymorphic procedures and incremental compilation. > (Those of you out there who have used Smalltalk and/or Lisp systems > know what I'm talking about.) Basically, the only reason *not* to > have dynamic binding is the belief that "it costs too much". Not so. Another reason to avoid dynamic binding is that doing so makes it easier to catch certain programming errors early on. The earlier an error is caught, the less damage it does.
gvcormack@watmum.UUCP (Gordon V. Cormack) (01/22/87)
> > Object-oriented programming is a religion that is currently in vogue. > > It adds little to the original class ideas of Simula 67, and the > > abstract data type ideas of Clu (which was inspired by Simula 67). > > > > Really the only thing that Smalltalk and its imitators > > add is dynamic procedure binding and dynamic type checking, which I > > regard as highly undesirable. > Dynamic binding yields considerable advantages over Simula, > including more polymorphic procedures and incremental compilation. > (Those of you out there who have used Smalltalk and/or Lisp systems > know what I'm talking about.) Basically, the only reason *not* to > have dynamic binding is the belief that "it costs too much". With > all the work that has been (successfully) done at making that fast > (method caches, class guessing, etc.) I hope we have put THAT myth > to bed. Method lookup consumes not very much (I remember it as 10%) > of Smalltalk execution time. 10% is a very small price to pay for > the benefits of being able to recompile and relink any procedure into > a running system (~1.5 MB source code) in only a few seconds! 1. The original point is that O-O adds nothing new. Certainly dynamic binding and polymorphism weren't new in O-O. 2. It is highly questionable that dynamic binding and static type checking are compatible. For a turing-machine equivalent language, it is undecidable what messages are sent to what objects. 3. Because of 2., there is a great deal to be gained by static binding/ type checking - namely some verification that the program does something reasonable. 4. Even Lisp programmers, etc., are discovering types - read Milner's paper on ML. 5. It is true that most strongly typed languages are straightjackets; some have great expressive power, flexibility, and polymorphism. 6. Class hierarchies (as in Simula67) give polymorphism without resorting to dynamic anything. 7. I still have not seen a satisfactory definition of O-O. I am not at all sure that one exists. I think it *is* essentially the Simula programming methodology invented 20 years ago by Dahl et al. -- Gordon V. Cormack CS Dept, University of Waterloo, Canada N2L 3G1 gvcormack@mum.waterloo { .CSNET or .CDN } gvcormack@water { UUCP or BITNET }
gore@nucsrl.UUCP (01/23/87)
> > [...] Basically, the only reason *not* to > > have dynamic binding is the belief that "it costs too much". > > Not so. Another reason to avoid dynamic binding is that doing so > makes it easier to catch certain programming errors early on. > The earlier an error is caught, the less damage it does. This is the part that troubles me most about run-time error checking. In order for an error to be noticed at run time, the program thread containing the error has to be executed. This may not happen until the program had been out in the field for many months (or years...). The only way to test for such errors it to have a test suite that executes every single branch in the software. Jacob Gore Northwestern University, Computer Science Research Lab {ihnp4,chinet}!nucsrl!gore
rentsch@unc.UUCP (01/25/87)
> > > [...] Basically, the only reason *not* to > > > have dynamic binding is the belief that "it costs too much". > > Not so. Another reason to avoid dynamic binding is that doing so > > makes it easier to catch certain programming errors early on. > > The earlier an error is caught, the less damage it does. > This is the part that troubles me most about run-time error checking. > In order for an error to be noticed at run time, the program thread > containing the error has to be executed. This may not happen until > the program had been out in the field for many months (or years...). > The only way to test for such errors it to have a test suite that > executes every single branch in the software. (I talked about this in the original article, but apparently not clearly enough. Let me try again.) The '> > ' poster seems to assume that dynamic binding implies certain errors (usually called "type errors") can only be caught at runtime. Not so. Systems with dynamic binding usually also include run-time checking. But, dynamic binding need not *require* run-time type checking. For example, Smalltalk-80 does require run-time type checking. But, if type declarations are added, the same language (and with the same interpreter) can be staticly typed and staticly type checked. When this is done, run-time type errors (e.g., "message not understood", etc.) cannot occur. For those interested, this has actually been done -- it was reported in POPL 1982. Note that having compile-time typing and type checking does not remove the need for dynamic binding. A polymorphic type (e.g., "'Stream' - like") argument does not require the same procedure for each actual argument, just arguments that supply the right methods. But which method gets invoked must still be looked up at run-time. Predicating his article on the run-time error checking assumption, the '> ' poster raises a valid point. On the other hand, isn't it common practice in software engineering to require execution of all software paths in test cases before releasing the product? (To be fair to the other point of view I will say that even this is not enough to guarantee no run-time errors -- to do that every COMBINATION of paths would have to be executed, which is not done in general, nor should it be. I am not trying to argue with his point, just make a side comment, and more importantly point out that his assumption is only an assumption.) cheers, Tim
shebs@utah-cs.UUCP (01/26/87)
In article <4000003@nucsrl.UUCP> gore@nucsrl.UUCP (Jacob Gore) writes: >In order for an error to be noticed at run time, the program thread >containing the error has to be executed. This may not happen until >the program had been out in the field for many months (or years...). >The only way to test for such errors it to have a test suite that >executes every single branch in the software. This has to be done anyway for reliable software - it's too bad that only a handful of publicly-available programs come with test suites, many folks don't realize that test programs are an important component of systems in the real world. Having compile-time type checking only finds the second-least-interesting class of mistakes (syntax errors being the least interesting). It does not do anything for semantic errors, such as those that flip F-16s upside down when crossing the equator... >Jacob Gore stan shebs
lsr@apple.UUCP (01/27/87)
In article <4000003@nucsrl.UUCP> gore@nucsrl.UUCP (Jacob Gore) writes: >This is the part that troubles me most about run-time error checking. >In order for an error to be noticed at run time, the program thread >containing the error has to be executed. This may not happen until >the program had been out in the field for many months (or years...). >The only way to test for such errors it to have a test suite that >executes every single branch in the software. > The same is true of pointers. How can you be sure that a bad pointer is not passed to a procedure? You have to do sufficient testing. There have been cases of bugs going undiscovered in large programs written with conventional techniques, so the problem is not unique to object-oriented programming. -- Larry Rosenstein Object Specialist Apple Computer AppleLink: Rosenstein1 UUCP: {sun, voder, nsc, mtxinu, dual}!apple!lsr CSNET: lsr@Apple.CSNET
gore@nucsrl.UUCP (01/27/87)
/ shebs@utah-cs.UUCP (Stanley Shebs) / 10:15 am Jan 26, 1987 / > Having compile-time type checking only > finds the second-least-interesting class of mistakes (syntax errors being > the least interesting). It does not do anything for semantic errors, > such as those that flip F-16s upside down when crossing the equator... This is true. Still, I've spent many, many hours tracking down errors that would have been detected by the compiler in other languages. Detecting some of the errors is better than nothing. Jacob Gore Northwestern University, Computer Science Research Lab {ihnp4,chinet}!nucsrl!gore