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: 1108a1,b87849933931bc93 X-Google-Attributes: gid1108a1,public X-Google-Thread: f43e6,b87849933931bc93 X-Google-Attributes: gidf43e6,public X-Google-Thread: 114809,b87849933931bc93 X-Google-Attributes: gid114809,public From: bs@research.att.com (Valerie Torres) Subject: Re: What is wrong with OO ? Date: 1997/01/04 Message-ID: X-Deja-AN: 207942956 references: <5acjtn$5uj@news3.digex.net> organization: AT&T Research, Murray Hill, NJ, USA newsgroups: comp.lang.c++,comp.lang.smalltalk,comp.lang.eiffel,comp.lang.ada,comp.object,comp.software-eng Date: 1997-01-04T00:00:00+00:00 List-Id: Jon S Anthony (jsa@alexandria) writes: > In article <5acjtn$5uj@news3.digex.net> ell@access1.digex.net (Ell) writes: > > > Jon S Anthony (jsa@alexandria) wrote: > > : With respect to this "led/leads" claim: Such as????? I can't think of > > : _any_ where this is true. Though I can think of at least one > > : important _implementation_ aspect where this seems to be true. > > > > Led (first or second) wrt the OO paradigm: Private data members, static > > resolution of overloaded functions, protected members, and multiple > > inheritance. Correct me if I'm wrong. Remember this is wrt the early > > '80's. > > Recheck your facts. Led/lead means "first" to me and certainly > carries that connotation around with it even if you want to pull a > Humpty Dumpty. It is very important getting the fact straight on a topic like this where many seem keen on confusing the question "is C++ innovative and if so compared to what and in which ways?" with "is C++ my favorite programming language?" or or even "is C++ perfect?" (my opinion: it is in some ways, it is for many things, it is not). The origins of C++ and the reasoning behind the various design decisions are well documented: Bjarne Stroustrup: A History of C++: 1979-1991. Proc ACM History of Programming Languages conference (HOPL-2). ACM Sigplan Notices. Vol 28 No 3, pp 271-298. March 1993. Also in History of Programming languages (editors T.J.Begin and R.G.Gibson) Addison-Wesley, ISBN 1-201-89502-1. 1996. Bjarne Stroustrup: The Design and Evolution of C++. Addison-Wesley. 1994. ISBN 0-201-54330-3. Note that the paper went through HOPL2's strict peer review process so that the likelyhood that what is claimed to be a fact really is a fact is much higher than in a net posting, in an unrefereed paper, or in a paper from a commercial journal. To the best of my abilities, the D&E book agrees with the HOPL paper on issues covered in both but provides much more information and context. It would have been nice if comparable information existed on the origins of most major languages. That would have made it easier to understand the different languages in context and see how ideas moved through the programming communities. The HOPL papers is a good start, but they differ too much in what kind of information they supply and tend not to be sufficiently detailed for my taste. Also, HOPL covers only a few languages. > Private data member stuff was in various languages > before "C with classes" was even conceived (e.g., CLU, Ada83). It > certainly existed in Eiffel before C++ was christened. Protected > capability was certainly in Eiffel-1 which predates C++. Same with > overload resolution (e.g., Algol68 had this as did Ada 83 compilers > that were in the field before CWC or C++). MI was in Eiffel from the > start and that predates its appearance in C++ for sure. First of all, we must be careful about dates. C with classes had "private" in 1979 and protected around 1981. Data abstraction language (such as Ada83) tends to have private only (you need inheritance for the private/protected distinction to be meaningful) whereas OO language (such as Smalltalk) tends to have protected only (whatever it may be called). I don't know if any language having both before C++ and I don't know of any earlier language expressing the dinction between implementation inheritance (private base) and interface inheritance (public base, subtyping). This pre-dates Liskov's formulation of her substitution principle by about 8 years. It is of course possible that some language had equivalent facilities at the time I designed those features for CwithClasses/C++ or that someone somewhere wrote a paper discussing the issues, but I didn't know of one so the protection facilities of C++ are independently developed. In addition to private, protected, and public, C++ offers the mechanism for selectively including names from a base in the interface of a derived class. That too may have been an innovation, but I don't really know. C++ introduced constructors with the possibility of having several as well as destructors (around 1980). All languages that support information hiding provides some form of initialization (and certainly Simula did), but I think the C++ mechanism provides a degree of flexibility that was novel. It is hard to really pin down what is innovative and what is not. For example, I credited Algol68 with C++'s ability to have declarations in conditions so that you can declare, initialize, and test in one place. However, I was (later) told by one of the people involved in the Algol68 design that although Algol68 logically ought to have had that feature, they didn't think of that in the right way at the right time, so Algol68 doesn't allow declarations in conditions. In other words. I had deduced that feature from the structure of Algol68 and failed to verify. There are literally hundreds of details that one could examine to try to determine their exact antecedence and give credit where credit is due. I do some of that in the history paper and in D&E, but here I'd like to point to a couple of bigger issues. C++ was designed to allow design and programming techniques from Simula to be used in the context of systems programming and other applications where run-time and space were critical. On way of looking at the task I set myself was to make data abstraction and object-oriented techniques affordable and accepted in a community that mostly didn't know of them and to the extent it did couldn't afford to apply those techniques given the languages available. To the extent that C++ succeeded at that, C++ was ahead of the wave, ``a leader'' borrowing the phrase from the original posting. It has always been my opinion that making something comprehensible and affordable is a worthwhile, innovative, and socially useful activity. I think producing 14 million volkswagen's or Ford Ts is at least as innovative as building a few thousands Rolls Royces or a few hundred formula-1 cars - even though the vast majority of the individual features first appear in the luxury and speciality cars. I think that the majority of areas where C++ has contributed have to do with economy and scale. C++ was designed to be useful rather than to be innovative. Wherever possible, I tried to follow a well-tested precedence. Thus, you can find ideas from Algol68, ML, Ada, Clu, and even BCPL in C++. The main ideas came from C and Simula, of course. Only where I couldn't find a solution that fitted in C++'s general framework and met my criteria for run-time efficiency, ease of implementation, ease of teaching, etc. (see D&E Chapter 4), did I feel compelled to try to invent something. Much of C++'s success has to do with fitting into existing environments and being compact and fast (yes, I know that these are not the aspects of C++ that are currently emphasized in the MS Windows world). The speed and compactness of code generated from C++ depends on a few fundamental design decisions that I think were novel at the time: The ability to easily link to existing languages and have C++ code used from other languages. (This is done through the linkage model and it is directly supported in the C++ grammar). The ability to use user-defined types and built-in types in the same way. In Simula - as in most data abstraction and OO language - every object of a user-defined type must be on the heap; this leads to overheads compared to stack-allocated objects. Similarly, C++ pointers work uniformly for both user-defined and built-in types. C++ offers objects of user-defined types with zero space overhead compared to C structs. C++ offers calls of member functions with zero time overhead compared to C functions. C++ offers inline member and non-member functions with zero overhead compared to macros. C++ offers its form of dynamic (run-time) resolution, virtual functions, with low and fixed overhead compared to ordinary function calls (20% to 100% dependent of implementation). C++ can be used without a significant run-time-support system and without significant libraries. These features were introduced in the 1979 to 1983 timeframe (virtual functions last!) and described in journals and at conferences from about 1981. This combination of feature was - and to some extent still is - unique and important to many. This efficiency is a large part of the reason why C++ was able to blaze a trail into areas where data abstraction and object-oriented languages had made essentially no headway. By demonstrating applicability and efficiency in new application areas and in new communities C++ opened opportunities to other languages with a different balance of tradeoffs. Both where C++ was successfully used and where problems were found, it opened a door to alternatives. People who didn't try to use OO and abstraction languages in the early days (say 1967 to 1989) typically seriously underestimate the obstacles to getting these languages and programming techniques into non-research use. Most would also be shocked at the state of their favorite language - as compared to its current state - in its early years. When comparing languages in a historical context we must consider not only if a language has a feature, but also when it had it, when it was published, when it was implemented, and whether those implementations were good enough for production use. > Next I suppose you will be trying to tell me it was the first to have > generics (templates) or namespaces or assignment attempt or RTTI or... Please refrain from making conjectures about what someone in a debate might claim. It adds no facts and can fuel flamewars. > C++ was and is a _follower_. That is not necessarily a bad thing, but > it is anything _but_ innovative. > > /Jon > -- > Jon Anthony > Organon Motives, Inc. > Belmont, MA 02178 > 617.484.3383 > jsa@organon.com Over the years, C++ has evolved within a framework that was reasonably well understood early on. During this evolution, C++ has borrowed from several languages (always with acknowledgements), but it has never been in the position of slavishly following fashion or systematically borrowing from a perceived competitor. C++ evolved within its own framework to meet the needs of its users. I don't think that can be fairly labelled "being a follower." As far as I know, Simula was the first language with structured RTTI (INSPECT and QUA). Some studies I made of Simula programs convinced me that the less RTTI was used the better the structure of an average program (INSPECT was commonly used in ways that precluded modularity). The C++ RTTI (primarily dynamic_cast) was introduced to handle the few cases where it is necessary and in a form that hopefully minimizes problems. Multiple inheritance is sometimes mentioned as innovative in C++. It existed in different - more powerful, but slower - forms in several Lisp dialects. I considered it for C++ from about 1981 and introduced it into C++ in a more static and type-safe form in 1987 after a couple of years of experimentation (a brief mention of C++ MI can be found in my "What is Object-oriented programming?" paper from 1985). The form of multiple inheritance in C++ may be innovative, the fundamental idea is quite old. I now consider MI essential for a language relying on static type checking. You can do without it of course (just like you can do without single inheritance and without classes), but the resulting code is contorted. In the area of exceptions, C++ may have added something important: C++ exceptions can be of arbitrary type and inheritance is taken into account when catching an exception. This provides important possibilities for grouping exceptions that I don't know precedence for (though the need for grouping has been known for decades). Templates are an interesting case. Naturally, many languages have provided macros, generics, type inference, etc. for decades. However, templates grew out of the needs of C++ programmers and seem to have a combination of features that provide a surprising expressive power. The (relatively new) C++ standard library of containers and algorithms seems to me to provide a unique combination of generality and efficiency. Naturally, the algorithms are not new (most can be found in Knuth), most languages provide containers which roughly correspond to what the STL offers, and many of the programming techniques used are borrowed (with thanks and acknowledgement) from the functional programming community. Should something like this be considered innovative? Would it be fair to say that it leads hundreds of thousands of programmers into areas of programming where they haven't been and would have been unlikely to reach for many more years? I think so. - Bjarne Bjarne Stroustrup, AT&T Research, http://www.research.att.com/~bs/homepage.html