dan@Apple.COM (Dan Allen) (04/13/88)
A brief critique of: "An Introduction to Object-Oriented Programming and C++" (Richard S. Wiener & Lewis J. Pinson. Addison-Wesley. ISBN 0-201-15413-7.) follows. Wiener & Pinson is definitely a needed book, as Stroustrup's book is somewhat hard to read, a fact admitted by many on the network. However, Wiener & Pinson (W&P) has a few flaws itself... My main concerns are with some of the definitions of object-oriented programming. At the last main conference on object-oriented programming, OOPSLA '87, Peter Wegner's paper entitled "Dimensions of Object-Based Language Design" gave the following definition of what it means for a language to be object-oriented: object oriented = objects + classes + inheritance Further definitions of these terms define objects to be instances of a class, and classes to be an organizational tool that allows inherited qualities to be passed to subclasses, etc. Now for the problems. Wegner goes on to define data-abstraction as an ORTHOGONAL attribute to object-orientedness, for the following reason(s): data abstraction and the notion of abstract data types provide for the description of a data structure and some associated function and procedures that have sole access to the data structure. Wegner's point is that object-oriented languages allow access to the underlying data structures BY DIRECT REFERENCE rather than only through the (to use OO language) associated methods of the class. OO languages can also use functions and procedures to access the data structure as well. Well, W&P do not make this distinction. Pages 1,2, and 57-58 particulary are full of definitions that are not in keeping with the main body of OO language designers. Now, what is C++ then? Well, C++ is interesting in that its classes are, by default, supportive of abstract data types and the data abstraction paradigm by making fields of a class private. (Remember, private data = Data Abstraction.) C++ also supports object-oriented programming by allowing fields to be declared public. (Public data = Object-Oriented if inheritance is also supported, which it is in C++). Now there is a definitional problem at hand: what if some fields are public and some fields are private? C++ has created a new definitional problem. I must point out that W&P is fairly consistent internally with the definitions that are used. My gripe is that they are using the same terms as the mainline Object-Oriented world, but with new and changed definitions. A few more guidelines with the definitions that I subscribe to: ** Ada is NOT object-oriented. Ada does support data abstraction. ** Object Pascal IS object-oriented, but does NOT support data ab. ** Modula-2 is NOT object-oriented. It does support ADTs. ** C++ supports both object-oriented programming & ADTs, though not at the same time. (Stroustrup's definitions are more in line, by the way, with mine and Wegner's than with W&P.) Sorry for the long flame about definitional problems, but I have been working with object-oriented languages for several years here at Apple and have found them a little hard to teach to people because of problems such as these. When Stroustrup came to Apple recently, he spoke about such matters and he seems to have a good understanding of these issues. His talk also was much more understandable than his book, so if you ever get the chance to hear him, make sure to take advantage of it. You'll enjoy it. I did. Dan Allen Software Explorer Apple Computer
johnson@uiucdcsp.cs.uiuc.edu (04/13/88)
I think it is unfair to criticise Wiener and Pinson because they didn't follow Wegman's terminology. First, they wrote their book before he wrote his paper. Second, Wegman's classification is not at ALL considered standard. It may become standard, but it isn't yet. I disagree 100% with the notion that object-oriented programming and data-abstraction are orthogonal. Actually, object-oriented programming is data-abstraction carried to extremes. Data-abstraction means that the programmer does not know how the "object" is implemented. O-o programming means that even the compiler does not know how the object is implemented! In other words, when the compiler "sends a message" (calls a virtual function) it doesn't know exactly which procedure is being called, but must depend on some kind of run-time binding. While I agree that inheritance is important, I think that message sending is more important. Thus, Emerald is object-oriented even though it doesn't have inheritance. Message sending can be used to fake inheritance with delegation. Of course, I prefer inheritance. Object-oriented languages most definitely do not have to allow direct access to their structure. In fact, I think that they should not. Smalltalk does not allow direct access to the instance variables of objects, except through instVar:at:, which is a kludge used for debugging. We never make C++ member variables public, but instead access them through member functions declared to be in-line. This means that we can easily reimplement the data structures in the class. So, I am disagreeing with the notion that the object-oriented world thinks that you should be able to directly access the fields of an object. Maybe your part of the world does, but mine does not, and mine is pretty big, too! I certainly agree that Ada and Modula-2 are not object-oriented but do support ADTs. The reason that they are not object-oriented is primarily because they do not support message passing (the Ada rendezvous doesn't count) and secondarily because they do not support inheritance. I am primarily a Smalltalk programmer, and am involved with several large Smalltalk projects, but I am also involved with the CHOICES operating system here at Illinois, which is an object-oriented o.s. written in C++. I use both languages in teaching. I probably think more like a Smalltalk programmer than like a C++ programmer, so that might explain my point of view. Ralph Johnson
dan@Apple.COM (Dan Allen) (04/15/88)
I am glad that we agree that Ada (and Modula-2) are not object-oriented. I suppose that this was a major thrust of my flame about the book, mainly because more and more people are both using Ada and are hearing the object-oriented buzzwords, and then think that they are programming in an object-oriented manner. I personally do NOT entirely agree with Wegner, but I DO think that it would be nice if we all shared a few common definitions of these terms, so that the incoming masses to object-oriented programming will get a clearer understanding of what the heck it all means... Which is what I am STILL trying to do myself... Thanks for your comments. Dan Allen Apple Computer
jima@hplsla.HP.COM ( Jim Adcock) (04/16/88)
I don't buy the idea that instance variables of an object must always be accessed via an access method. I think there are good cases for violating this "rule". The simplest case that comes to mind is the overused example of complex numbers. To suggest that: x = myComplexNumber.re(); y = myComplexNumber.im(); is in any way better than: x = myComplexNumber.re; y = myComplexNumber.im; seems ludicrous to me. In fact, I believe that in many situations similar to the complex number example, allowing direct access is preferrable to forcing the class's user to always tag on the "meaningless" () parenthesis. In any case, I believe the important operative rule that's in effect here is that the class definer define the public portion of the interface to his/her class in a way that is not going to change in future revisions of the class. If you, the designer, are willing to "guarantee" that those portions of your object that you allow access to directly are not going to change in future revisons of your class, then I say, "no problem, give the class user direct access." If you don't feel you can make such a guarantee, then please make sure to supply access functions instead of allowing direct access to those instance variables that may be changed in future revisions. [If in doubt, use access functions]
johnson@uiucdcsp.cs.uiuc.edu (04/16/88)
Simon Kaplan, who has an office two doors down from mine, has a sign on his door that reads Ada is good. Object oriented is good. Therefore, Ada is object oriented. I think that is the best argument for why Ada is object-oriented!
shopiro@alice.UUCP (04/17/88)
In article <6590037@hplsla.HP.COM>, jima@hplsla.UUCP writes: > I don't buy the idea that instance variables of an object must always > be accessed via an access method. > To suggest that: > > x = myComplexNumber.re(); > y = myComplexNumber.im(); > > is in any way better than: > > x = myComplexNumber.re; > y = myComplexNumber.im; > > seems ludicrous to me. Here are two reasons you might prefer access functions. 1) Access functions allow you to change the internal representation. You might someday want to represent complex numbers in polar coordinates. Admittedly, rectangular coordinates are usually preferred, but there undoubtedly are applications in which polar coordinates would be better. Use access functions and all your code will continue to run. 2) Access functions support read-only access to instance variables. You might someday want a redundant represention of complex numbers using both rectangular and polar coordinates. You then need to preserve the consistency of the two parts of the representation. If you allowed the user direct access to the instance variables, that consistency could be destroyed by any code that accessed a complex number. If you use access functions, you only have to worry about member functions. I should also mention that there is no performance penalty for access functions. If they are expanded inline the generated code is exactly the same as reading a public instance variable. On the other hand C++ does allow public instance variables, so you can make your own decision. > In fact, I believe that in many situations similar to > the complex number example, allowing direct access is preferrable to forcing > the class's user to always tag on the "meaningless" () parenthesis. I will agree that the required () for access functions may seem annoying, but if you agree with me that all syntax is painful, then I hope you'll also agree that this is only a minor turn of the screw. (:-) -- Jonathan Shopiro AT&T Bell Laboratories, Murray Hill, NJ 07974 research!shopiro (201) 582-4179
ark@alice.UUCP (04/17/88)
In article <6590037@hplsla.HP.COM>, jima@hplsla.UUCP writes: > To suggest that: > x = myComplexNumber.re(); > y = myComplexNumber.im(); > is in any way better than: > x = myComplexNumber.re; > y = myComplexNumber.im; > seems ludicrous to me. Not at all. If you allow MyComplexNumber.re without parentheses, you're stuck if you ever decide to start using polar coordinates.
jima@hplsla.HP.COM ( Jim Adcock) (04/20/88)
|1) Access functions allow you to change the internal representation. |You might someday want to represent complex numbers in polar |coordinates. Admittedly, rectangular coordinates are usually |preferred, but there undoubtedly are applications in which polar |coordinates would be better. Use access functions and all your code |will continue to run. If you refuse to stick to your original definition of blah, and you make blah public, and someone uses blah, and then you change your definition of what blah means, then that user of your class is going to be hosed. BUT this is true whether or not blah is an access function or a public instance variable. If you change your definition of what a public anything means, you will hose your users. So the penalty for using access functions "everywhere" comes down to: 1) "Needlessly" writing access methods to instance variables that you, the class writer, are committed to never changing. 2) The class user gets more exposure to the use of the "noise characters" () And like other cases of "noise characters" in computer languages this is stuff that is easy to forget, since its meaningless. Meaning more failed compiles. And a few more characters to type. 3) The obscuring of an important, practical engineering issue -- namely that if a class designer changes the meaning of ANY PART of his/her public interface, in general that class's users are going to be hosed -- by the use of a blanket "religious" statement: "Use access functions everywhere and you can change your class without your users." Again, not true -- the issue is public vs non-public, it is not an issue of access functions or not access functions. Change the meaning of any part of your public interface, either instance variable or function, and your class's users will be hosed.
shopiro@alice.UUCP (04/22/88)
In article <6590039@hplsla.HP.COM>, jima@hplsla.UUCP writes: > If you refuse to stick to your original definition of blah, > and you make blah public, and someone uses blah, and then you change > your definition of what blah means, then that user of your class is > going to be hosed. > > BUT this is true whether or not blah is an access function or a public > instance variable. If you change your definition of what a public > anything means, you will hose your users. (This should be obvious, but ... ) Suppose you have class Complex { double re, im; public: double real() { return re; } // ... }; and you decide you want to switch to polar coordinates. Then you can write class Complex { double rho, theta; public: double real() { return <trig expression>; } // ... }; and users will not be affected. > ... Change the meaning of > any part of your public interface, either instance variable or function, > and your class's users will be hosed. But use access functions so you can change the internal structure of your class without changing the meaning of its public interface. -- Jonathan Shopiro AT&T Bell Laboratories, Murray Hill, NJ 07974 research!shopiro (201) 582-4179
chip@ateng.UUCP (Chip Salzenberg) (04/22/88)
In article <6590037@hplsla.HP.COM> jima@hplsla.HP.COM (Jim Adcock) writes: >I don't buy the idea that instance variables of an object must always >be accessed via an access method. I think there are good cases for >violating this "rule". Sometimes. Maybe. But when it's debugging time, It's _so_ easy to insert: cerr << "I'm being changed!\n"; into the modification function. >[If in doubt, use access functions] Amen. -- Chip Salzenberg "chip@ateng.UU.NET" or "codas!ateng!chip" A T Engineering My employer may or may not agree with me. "I must create a system or be enslaved by another man's." -- Blake