dmg@ssc-vax.UUCP (David Geary) (06/01/89)
I've been programming in C for about 5 years, and just recently started using C++. I would like to start a discussion of Eiffel vs. C++. I understand that both languages use C as a base language, and that both implement OOP features, and it seems as though the two have much more in common, aside from syntactic differences, than they have differences. Note that I'd like the discussion to center around version 2.0 of C++ vs. the most current version of Eiffel. I am aware of the fact that Eiffel has a robust library of base classes, but I would like to see a discussion of language *features*. About the only difference that I can discern is the fact that Bertrand Meyer posts more often to comp.lang .eiffel than Bjarne Stroustrup posts to comp.lang.c++ ;-) ;-) -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~ David Geary, Boeing Aerospace, Seattle ~ ~ "I wish I lived where it *only* rains 364 days a year" ~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sarkela@eiffel.UUCP (John Sarkela) (06/03/89)
> I've been programming in C for about 5 years, and >just recently started using C++. I would like to >start a discussion of Eiffel vs. C++. I understand >that both languages use C as a base language, and >that both implement OOP features, and it seems as >though the two have much more in common, aside from >syntactic differences, than they have differences. First, consider the relative grammatical complexity of the languages. Eiffel is an LL(1) language, whereas net comments seem to suggest that C++ may not even be LALR(1). Much of the grammatical complexity of C++ seems to derive from its historical precedents. The simplicity of the Eiffel grammar has much to do with the fact that it does not attempt to be source compatible with prior languages. Eiffel, the language, is not C based. The relation which Eiffel shares with C is solely that of source language to target language. Second, consider some the features of C++ which Eiffel does not possess. Eiffel does not possess global variables. Eiffel does not possess pointers. The elimination of gratuitous pointer aliasing and extern'ed globals allows a smart compiler greater lattitude in generating optimized code. Third, consider features of Eiffel which C++ does not possess. One of the stronger motivations for using object oriented techniques, is to take advantage of sharing at least specifications and hopefully implementations. With untyped object languages such as Smalltalk this follows naturally. In the case of statically typed languages, however, the denotations for collection, aggregate, or container classes must either be duplicated for each contained type or or the container must be parameterized by the contained type. The Eiffel generic class parameter language construct directly addresses this issue. While ad hoc mechanisms may be used to rewrite nearly duplicate class declarations in a language which does not support genericity, IMHO it is perhaps better to put all type parameterizations within the scope of the language type system. Eiffel has included for some time multiple inheritance. At this point in time, I do not have access to a description of MI in C++. Given a familiarity with C, however, I expect that namespace traditions of C could make MI a subtle feature of C++ Rev. 2.0. Finally, consider one of my favorite uses of MI in Eiffel, the specification class. Given the ability to specify class invariants, and method pre and post conditions, one can write a specification class which fully qualifies the domains and ranges of all class methods. Eiffel provides language hooks which allow straight forward specification of these qualities independent of the implementation of the components. One thus may use multiple inheritance to provide both a "is-a" categorization of the refined class as well as the "code reuse" of implementation inheritance. I don't have C++ 2.0 documentation so I don't know the extent of exception support, nor do I know the rules for MI in C++, can anyone give a definitive explanation? BTW, can anyone clear up exactly how one specifies the input restrictions and legitimate outputs of library C++ components? Conclusion: Eiffel is a grammatically simpler language than C++. Eiffel does not have many language features that C++ inherited from C. Eiffel has language support for component specification and qualification. John Sarkela sarkela@eiffel.com
UH2@PSUVM.BITNET (Lee Sailer) (06/04/89)
While I agree with most of this comment, I want to clear up one possible small understanding. In article <148@eiffel.UUCP>, sarkela@eiffel.UUCP (John Sarkela) says: > >Eiffel does not possess pointers. The elimination of Lest programmers get the wrong idea, let me say that Eiffel DOES have a mechanism that allows things to point at one another. In C (and C++, I guess) a pointer might be better called an "address". C is famous for offering the programmers access to low level machine primitives such as memory addresses, as you all know. The probelm is that the compiler cannot possibly know what the programmer intends to do with the address, and thus cannot optimize well. The same argument has been made about strings---C does NOT have a string type. We fake it with pointers (addresses) and arrays (pointers 8-). In a language that does have a specific string data type, the compiler writer has a chance to do some optimization tricks otherwise not available. >gratuitous pointer aliasing and extern'ed globals allows a >smart compiler greater lattitude in generating optimized code. > >Third, consider features of Eiffel which C++ does not possess. >One of the stronger motivations for using object oriented >techniques, is to take advantage of sharing at least specifications >and hopefully implementations. With untyped object languages such >as Smalltalk this follows naturally. In the case of statically >typed languages, however, the denotations for collection, >aggregate, or container classes must either be duplicated for >each contained type or or the container must be parameterized >by the contained type. The Eiffel generic class parameter >language construct directly addresses this issue. While >ad hoc mechanisms may be used to rewrite nearly duplicate >class declarations in a language which does not support >genericity, IMHO it is perhaps better to put all type >parameterizations within the scope of the language type system. > >Eiffel has included for some time multiple inheritance. At >this point in time, I do not have access to a description >of MI in C++. Given a familiarity with C, however, I expect >that namespace traditions of C could make MI a subtle >feature of C++ Rev. 2.0. > >Finally, consider one of my favorite uses of MI in Eiffel, the >specification class. Given the ability to specify class invariants, >and method pre and post conditions, one can write a specification >class which fully qualifies the domains and ranges of all class >methods. Eiffel provides language hooks which allow straight forward >specification of these qualities independent of the implementation >of the components. One thus may use multiple inheritance to provide >both a "is-a" categorization of the refined class as well as the >"code reuse" of implementation inheritance. I don't have C++ >2.0 documentation so I don't know the extent of exception support, >nor do I know the rules for MI in C++, can anyone give a definitive >explanation? > >BTW, can anyone clear up exactly how one specifies the input restrictions >and legitimate outputs of library C++ components? > >Conclusion: Eiffel is a grammatically simpler language than C++. >Eiffel does not have many language features that C++ inherited from C. >Eiffel has language support for component specification and qualification. > > >John Sarkela sarkela@eiffel.com
sarima@gryphon.COM (Stan Friesen) (06/04/89)
In article <2689@ssc-vax.UUCP> dmg@ssc-vax.UUCP (David Geary) writes: > > I've been programming in C for about 5 years, and >just recently started using C++. I would like to >start a discussion of Eiffel vs. C++. I understand >that both languages use C as a base language, and >that both implement OOP features, and it seems as >though the two have much more in common, aside from >syntactic differences, than they have differences. > >... I may as well put in my two cents worth. My impression is that Eiffel is a "higher level" language than C++. That is Eiffel is a very strongly typed OOP language, with a very simple, limited implementation of objects, whilc C++ is a very flexible language that allows you to get into the guts of the system when you need to. Thus, as someone else stated, Eiffel feels like Pascal and C++ feels like C. Eiffel is very simple syntactically, at the cost of requiring you to do everything its way. In particular, except for the basic scalar types, *everything* is a class. There are no seperate derived types, such as pointers and arrays. A class instance is essentially always a pointer, but without the ability to do pointer arithmetic, or in fact anything except allocate, deallocate, and dereference. Thus it acts like a dynamically allocated instance of an object. (In fact this is what Meyer would call it, rather than a pointer). Because of this there are a number of things not possible in the language. For instance the standard library class ARRAY, used to make array objects via inheritence, had to be implemented in C and grafted into the language using the "foreign" language import capability. This limitation is not often important, since most of the common cases where going outside of Eiffel have been anticipated and included in the standard library. C++, on the other hand, is more complex because it allows you to decide how you want to implement something. It has built in all of the scalar and derived types from C, thus allowing direct manipulation of low-level implementation details when necessary. It still has all of the class features that facilitate OOP. It has dynamic allocation, when needed, and it allows run-time typing (using virtual functions). But if you don't need them you don't have to take them. Thus the trade-off is a simpler, easier to understand language versus one that gives you more control. > > About the only difference that I can discern is the >fact that Bertrand Meyer posts more often to comp.lang >.eiffel than Bjarne Stroustrup posts to comp.lang.c++ >;-) ;-) > Well, Bjarne Stroustrup used to post here occasionally, but he claims to be too busy now. So Andrew Koenig has taken over posting here for him. -- Sarima Cardolandion sarima@gryphon.CTS.COM aka Stanley Friesen rutgers!marque!gryphon!sarima Sherman Oaks, CA
bertrand@eiffel.UUCP (Bertrand Meyer) (06/05/89)
From article <2689@ssc-vax.UUCP> by dmg@ssc-vax.UUCP (David Geary): > I would like to start a discussion of Eiffel vs. C++. [...] > About the only difference that I can discern is > [joke about compared newsgroup patterns]. Since we often get the question of Eiffel versus C++, Mr. Geary's initiative provides a welcome opportunity to clarify what I see as the major differences. I am the main designer of Eiffel, so the following discussion cannot claim to be that of an independent observer, although it is certainly honest, and technically correct to the best of my knowledge. In all likelihood, others will contribute different viewpoints. I certainly cannot claim to be a C++ expert. If I misrepresent C++ in any way, it will be by mistake, not design. Should this occur, someone will certainly correct the mistake, either by writing to me (in which case I will post the correction if it does turn out that I have written something wrong) or by posting directly. This response has three sections: general observations; technical differences; conceptual differences. I apologize for its length; there is really a lot to say. Also, there is little new in the material below, much of which may be found in previous publications about Eiffel; none of my previous publications, however, has studied Eiffel from the point of view of a comparison with C++. Although I believe that the Eiffel environment and tools and the standard Eiffel libraries provide some of the major arguments for Eiffel, I will (with two exceptions explained below) limit the discussion to the languages proper, so as to abide by Mr. Geary's request: > I am aware of the fact that Eiffel has a robust > library of base classes, but I would like to see > a discussion of language *features* 1 - GENERAL OBSERVATIONS ------------------------ Eiffel was designed in 1985, initially not as a language for the rest of the world, but as an internal tool for a development that Interactive Software Engineering started at that time. We would have preferred to use an existing language and environment, but an examination of possibilities, including C++, quickly showed that nothing was even close to the minimum required for developing software according to the modern principles that I (then still a professor at the University of California, Santa Barbara) was teaching to my students. I did not want to develop a split personality or to fall into the ``do as I say, not as I do'' syndrome. I am mentioning this because in a way we had an unfair advantage: when we started, C++ existed. Although we certainly did not imitate C++, its very existence was helpful because it showed clearly what we did *not* want Eiffel to be. In a similar vein, we also looked at Ada, although in this case the ratio of positive to negative influences was higher. Even though Ada is not an object-oriented language, its syntax conventions and its handling of elementary constructs (expressions, control structures etc.) definitely influenced the corresponding Eiffel constructs. (By the way, only three languages did exert a strong semantic influence on Eiffel. One was Simula 67; the other two were not programming languages but specification languages: Abrial's Z, in whose design I was somewhat involved around 1978-79, and my own M, a successor to Z and to this day an unfinished design. A less important influence was Alphard.) Finally I do not think that in the long term Eiffel is really ``competing'' with C++. They have almost nothing in common in their aim and spirit, as explained in the final section of this message. In my undoubtedly biased view, the real competitor to Eiffel is Ada. (``Competitor'' for me is a positive word. When you acknowledge a design as a competitor to yours, it implies respect.) Ada, as already mentioned, is not truly object-oriented, but its official charter (reliability, reusability, professional high-quality software development etc.) is very similar, on paper at least, to that of Eiffel. 2 - TECHNICAL DIFFERENCES ------------------------- Software structure Eiffel software is organized in autonomous software units (classes), meant to be compiled separately. There is no main program. This is what I believe should be the case in object-oriented programming. In contrast, I understand that C++ still follows the traditional C model. Quoting from Dr. Bjarne Stroustrup's ``The C++ Programming Language'' (Addison-Wesley, 1986), which seems to be the major reference on C++, page 22, lines 13-14: ``A C++ program typically consists of many source files, each containing a sequence of declarations of types, functions, variables, and constants''. This is very far from the object-oriented model of software decomposition. Furthermore, reports from actual users of C++ seem to indicate a heavy use of ``include files'', a technique which I don't fully understand in the C++ context, and which has no equivalent in Eiffel. Assertions A fundamental property of Eiffel software is that it may be equipped with assertions. Assertions are elements of formal specification that serve to characterize the semantics of classes and their routines independently of their implementation. Assertions include in particular routine preconditions (which must be satisfied when a routine is called), routine postconditions (ensured by the routine on exit) and class invariants (global consistency conditions applying to every instance of a class). Assertions are essential for documenting components. As a matter of fact, I do not understand how one can talk about the very idea of reusable software components without assertions. Using a hardware analogy, a software component without assertions is similar to, say, an amplifier without precondition (the acceptable input voltage), postcondition (the gain, expressed as acceptable ratio of output to input) and invariant (including for example the temperature limits expected and maintained by the amplifier). Yet of widely available programming languages, only Eiffel has these notions. (A system that does have assertions, and in fact ones that are more sophisticated than Eiffel's current ones, is David Luckham's Anna system, developed at Stanford on top of Ada. As far as I know, however, this is not a deliverable product.) Beyond their documentation uses, assertions, which optionally may be monitored at run-time, provide a remarkable debugging and testing aid. At the recent International Eiffel conference in Paris, one user organization (Cognos Inc.) reported that they no longer perform traditional unit testing, having replaced it by assertion monitoring. Exceptions Eiffel has exception handling. Its exception mechanism is original and I believe it is one of our major contributions, based on the theory of ``Programming by Contract''. As far as I know, there is no exception mechanism in C++. I believe that one cannot write serious software without having a way to recover cleanly from unexpected cases. Global variables Consistent with the absence of main program is the absence of global variables. Global variables are well known to be detrimental to modularity and more generally to quality. The Eiffel technique of ``once routines'' is used to ensure disciplined sharing between classes when needed. (See my column in the Journal of Object-Oriented Programming, vol. 1, no. 3, pages 73-77, ``Bidding Farewell to Globals''.) In contrast, C++ seems to support global variables in the C style. Genericity Eiffel classes may be generic, i.e. parameterized by types, as in LIST [T]. Here actual uses of the class may use any type (class) as actual generic parameter, as in my_list: LIST [TEXT_LINE] The genericity may be constrained, as in MATRIX [T -> NUMERIC], which specifies that actual generic parameters must be descendants, in the sense of inheritance, of class NUMERIC (equipped with the operations "+", "-", "*" etc.). Descendants of NUMERIC include (in version 2.2) predefined types such as INTEGER and REAL. The operations of NUMERIC are available, within the class, on any variable of type T - so that it can define, for example, routines for adding and multiplying matrices. Note that in this example MATRIX itself might inherit from NUMERIC. Nothing of the sort exists in C++. This means that generic structures must be simulated by forcing type conversions, or ``casts'', using low-level C techniques. This defeats any attempt at static typing. A paper was published not long ago about a proposal for class parameterization in C++. (Although the paper was published in a refereed journal, it regrettably did not mention any of the two object-oriented languages that offer such a facility: Eiffel and Trellis-Owl, the latter designed by Craig Schaffert and others from DEC). Since by all reliable accounts the inclusion of such a facility in any form accessible to C++ users is several years away, it cannot be considered in any serious discussion. On that kind of time scale one can promise anything. Dynamic binding Dynamic binding is the default mechanism for routine calls in Eiffel (achieved without any undue effect on performance). The default policy in C++ is static binding; dynamic binding is only applied to routines declared as ``virtual''. This may look like an acceptable requirement to impose on programmers but I believe it is not. The whole idea of inheritance is that you may reuse a class later on by writing a descendant and adapting it to new uses by overriding some of the routines of the original - within the original semantic constraints, as defined by assertions. This should be done without impacting the original, which may be used by many other ``client'' classes. (These concepts are explained in my book ``Object-Oriented Software Construction, Prentice-Hall, 1988, as the ``Open-Closed Principle'', section 2.3.) In such a case the designer of the original routine may have had no inkling whatsoever that the routine would ever be redefined and subjected to dynamic binding. This is incompatible with the requirement that the original designer should have declared the routine as virtual in the first place. Instead of forcing the programmer to take care of low-level optimizations, the Eiffel approach makes the compiler responsible for exploiting the performance of static over dynamic binding. The optimizer, working on a set of classes, generates code that applies static binding to any routine which warrants it (because it is never redefined). Performing tedious and potentially dangerous optimizations in a safe way should be the role of computers, not humans. In-line expansion In C++ as in Ada a routine may be declared as ``in-line'', meaning that calls will be expanded in-line to gain performance. No such mechanism is available in Eiffel. Contrary to what one might think at first sight, I believe this to be a serious advantage for Eiffel. As soon as a routine is declared as in-line, its usefulness is severely limited because it no longer is a normal routine that can be redefined and subjected to dynamic binding. The discussion of the previous paragraph applies even more strongly. In Eiffel, once again, the corresponding optimizations are performed by the compiler, not by the human user. The optimizer will automatically expand certain routines in-line based on systematic criteria beyond programmer control. One of the criteria is of course that the routine not be subject to redefinition and dynamic binding; the number of calls in the code is another. Again, this seems the safe and efficient approach. Computers can perform this kind of task both more efficiently and more safely than humans. Operator overloading The term ``operator overloading'' is not entirely adequate since the issue is whether functions may be assigned names that will be used in prefix or infix form in calling expressions. This is a syntactic, not a semantic issue; the more important form of overloading, the semantic one, is provided in the object-oriented context by redefinition and dynamic binding. C++ offers the possibility of using an operator (from a set of predefined ones) as function name; a similar possibility is offered in Eiffel 2.2, although it was not present in earlier releases. So the two languages are indeed comparable in this respect. Consistency of the type system Beginning with version 2.2, Eiffel has a fully consistent type system in which every type, including basic types such as INTEGER, REAL and so on, is defined by a class (using the multiple inheritance mechanism). This was made possible by the introduction of the notion of expanded class, of special BITS M classes (whose instances are bit strings of length M), and of infix/prefix operators as discussed above. This is achieved without any effect on the efficiency of dealing with simple values such as integers, characters and the like. The advantage is mainly a conceptual one - being able to work with a single set of concepts admitting few special cases. There doesn't seem to be anything similar in C++, which uses the C types as basis. Type checking Because of the absence of genericity and the presence of the full C type system with its casts and other unsafe mechanisms, C++ cannot be reasonably be called a statically typed language. In contrast, Eiffel was designed as fully typed. The present Eiffel compiler misses a small number of type violations (arising in particular from cases in which polymorphism enables a client to evade an export or redefinition constraint). These cases seldom arise in practice, which is not an excuse for not handling them properly. Even with the current implementation, however, Eiffel is incomparably more type-safe than C++ because of the presence of genericity, of the strict enforcement of type checks in assignments, and of the absence of any unsafe casts or conversions. Friend functions C++ has a notion of friend function which, as I understand it, makes it possible to define routines outside of the object-oriented framework. There is nothing equivalent in Eiffel. This facility is not missed; I would see its introduction as a dangerous violation of the object-oriented principles. Deferred classes An extremely important notion in Eiffel is that of deferred class, which describes a non-fully-implemented abstraction. Deferred classes are used to capture commonalities and are central to the object-oriented approach. Two aspects are particularly important: the ability to define a partially deferred class, which contains both implemented and non-implemented routines; and the ability to attach assertions to a deferred class and its deferred routines, and thus to specify the behavior of yet to be implemented software. C++ as described in published references does not appear to support a similar notion. I have heard, however, that the forthcoming version of C++ has a notion of abstract class, which is meant to play the same role. Perhaps someone will describe this facility in detail so that readers can judge. Multiple inheritance Multiple inheritance is fundamental in the Eiffel approach. We made every effort to handle it in a very clean way; name clashes, in particular, are treated in what I believe is the right way. (More precisely, I do not know of any satisfactory solution in any other language. This is a strong statement, and proponents of other languages are welcome to respond to the challenge.) The published references on C++ systems exclude multiple inheritance which, however, is rumored to be imminent. I must confess this is one aspect on which we, at Interactive Software Engineering, are rather touchy. The first time I personally heard about the ``imminence'' of multiple inheritance in C++ was November of 1986. Since then, that is to say for two years and a half, we have essentially been unable to use the presence of multiple inheritance as an argument for Eiffel - so successful have others been in persuading almost everyone that multiple inheritance in C++ was around the corner. Here I would like to appeal to developers of software tools and suggest a universal ethical rule: whenever you refer to a feature that is not yet available in the released distribution of your product, mention it unambiguously in every relevant publication, together with an estimated date of availability (to the public, not internally). The name for such a policy is simple: honesty. This being said, it is indeed possible that multiple inheritance will become available in C++ during my lifetime. It is not clear from what I have read and heard that the non-trivial problems of multiple inheritance, such as name clashes, have been properly addressed. (If I am wrong on this, please enlighten me.) Renaming Eiffel offers a powerful technique in connection with inheritance: renaming. A class can rename inherited routines and attributes (i.e. methods and attribute variables for those who prefer such terms). This is used for removing name clashes in multiple inheritance and also, perhaps even more importantly, to provide locally adapted terminology when you inherit the right features but under the wrong names. As discussed in my OOSC book referenced above (section 10.4.7) and in a JOOP column (Vol. 1, no. 4, pages 48-53), this is essential if inheritance is to provide support for reusability in a practical industrial context. Garbage collection This item and the next violate Mr. Geary's request to limit the discussion to language features. I have included them anyhow because, even though they are environment rather than language features, they are made possible or next-to-impossible by the language design. To write serious object-oriented software, which at run time will inevitably generate many objects, some of which may become useless, one needs a good garbage collector. This is the case in Eiffel (which uses an incremental, parallel scheme so as not to impair performance). As far as I know, C++ systems do not support garbage collection, which would be extremely difficult if not impossible to implement because of the presence of C types and mechanisms. Automatic recompilation One of the most important practical aspects of Eiffel is the automatic compilation mechanism, based on automatic analysis of inter-class dependencies (multiple inheritance and client). This removes the need for make files and include files. Although I recall some seemingly interminable notes on the feasibility (or lack thereof) of a similar mechanism in comp.lang.c++, I don't know of any implemented mechanism for C++. Again, this seems due to the very design of the language; and again, the difference seems to result from irreconcilable views of what should be done by computers and what should be the province of humans. The Eiffel view is that error-prone and tedious management tasks should be handled by tools, and that programmers should concentrate on solving programming problems. Pointer arithmetic etc. One of my major objections to C++ stems from what that language has rather than what it has not. Because C++ retains almost total compatibility with C, it keeps all its low-level and dangerous features. The design of C dates back to the late sixties and is obsolete by modern software engineering standards. Compatibility with C means that in C++ you still have pointers, type casts, pointer arithmetic, function pointers, malloc, free, bizarre operator precedence (the famous asterisk/parenthesis bugs), weak type checking and so on. I strongly disagree with this approach if the goal is to obtain software quality. Take pointer arithmetic, for example. I would contend that you can have quality software, or you can have pointer arithmetic; but you cannot have both. In Eiffel, the choice has been made. None of these low-level features are present (as John Sarkela pointed out in a previous message); needless to say, they are not missed. Compatibility with C software C++ is obviously very compatible with C. But in Eiffel too you can easily communicate with C software; both call-in and call-out are provided. This makes it possible to reuse existing software easily. The need for such communication was not, however, deemed to be a good argument for impairing the consistency of the language itself. Simplicity and ease of learning Much of the plea for C++ is based on the observation that it provides an easy transition from C, which (for better or worse) is the language many programmers know nowadays. Using Dr. Brad Cox's expression (meant for Objective-C), this supports an ``evolutionary'' approach. I can certainly respect this view and its appeal to software managers in industry. But I believe that by considering it more closely one will find it short-sighted and ill-founded. Learning a new language such as Eiffel is nothing for a competent programmer. For Eiffel, which is small and simple, the learning process typically lasts a few days at most. Nobody has ever told us that Eiffel was difficult to learn. (If you read this, have tried to learn Eiffel, and found otherwise, please respond!) I believe that the process of going to Eiffel is in fact much smoother, as you don't have to use a confusing mix of old and new concepts. In a language that you master totally, you feel confident and you can concentrate on your job rather than on the language intricacies. Also, the brief initial shock produced by the realization that you cannot easily write your programs in a traditional way any more is, in the experience reported by Eiffel users, highly salutary. 3 - CONCEPTUAL DIFFERENCES -------------------------- The considerable differences listed above more than offset, in my mind, any similarity that may seem to exist between Eiffel and C++. Beyond these individual technical differences, the contrast between the two languages is deep and conceptual. Eiffel is a new language and environment designed with a precise charter (enabling the production of very high quality software by professional programmers). C++, as I see it, is an attempt at a more modern version of C. (The basic C++ reference quoted above, in its ``historical note'' on page 5, writes that ``the difference between C and C++ is primarily in the degree of emphasis on types and structures'') . There are undoubtedly arguments for both approaches. Needless to say, I find the arguments for the first to be stronger. -------------------- This is probably overkill already and I shall resist the temptation to go on. Have I at least succeeded in convincing Mr. Geary that the technical differences are deep ones? In all likelihood, this note, prompted by Mr. Geary's question, will eventually be rewritten as a short article, so that comments and criticism will be greatly appreciated. -- Bertrand Meyer bertrand@eiffel.com
lam@tridom.uucp (Larry Morris) (06/06/89)
In article <150@eiffel.UUCP>, bertrand@eiffel.UUCP (Bertrand Meyer) writes: > > Finally I do not think that in the long term Eiffel is really > ``competing'' with C++. They have almost nothing in common in their aim > and spirit, as explained in the final section of this message. > In my undoubtedly biased view, the real competitor to Eiffel is Ada. > (``Competitor'' for me is a positive word. When you acknowledge > a design as a competitor to yours, it implies respect.) > Ada, as already mentioned, is not truly object-oriented, but its official > charter (reliability, reusability, professional high-quality software > development etc.) is very similar, on paper at least, to that of Eiffel. > I find this view surprising, even though I'm willing to concede that Eiffel is radically different from C++, and more modern in its design. Ada, from what I've seen, is used more by mandate than choice [not that it's a particularly "bad" language, but I'd be willing to bet that nearly all new engineering users of Ada have a DoD standard on their desks]. Setting up Ada as the "competition" seems like a strawman to me. As for the "charter" of C++, was it intended for unreliable, one-time, amateur, poor-quality software development? I doubt that Stroustrup's intent was significantly different than yours. I see C++, Objective-C and Smalltalk as Eiffel's most obvious competitors for the engineering marketplace, as much for political as design considerations. Ada is likely to remain comfortably entrenched in its own well-protected market. > can talk about the very idea of reusable software components without > assertions... > maintained by the amplifier). Yet of widely available programming > languages, only Eiffel has these notions. Assertion checkers, of course, have been used for years as tools outside the scope of the language, as libraries, or extracted by tools from code comments. Placing assertions within classes as part of the language is, I must agree, a very powerful feature. But Eiffel's design philosophy calls on programmers to define their classes with assertions in addition to coding their implementation; something most programmers aren't used to doing and may view as an onerous task. Since assertion checking isn't any better than the assertions dreamed up by the programmer, I'm skeptical of using it to "replace" unit testing. > > Eiffel has exception handling. Its exception mechanism is original and > I believe it is one of our major contributions, based on the theory of > ``Programming by Contract''. As far as I know, there is > no exception mechanism in C++. I believe that one cannot write > serious software without having a way to recover cleanly from unexpected > cases. > I agree 100% with this, and I view it as the single biggest selling point of Eiffel over C++. > > In C++ as in Ada a routine may be declared as ``in-line'', meaning > that calls will be expanded in-line to gain performance. No such mechanism > is available in Eiffel.... > The optimizer will automatically > expand certain routines in-line based on systematic criteria beyond > programmer control... > I'm a bit skeptical about this approach. In data communications software (or other types of real-time software) it's frequently necessary to optimize certain methods heavily. I'd like some choice over this without having to resort to an assembly language or C call-out. How many times must I reference the method before your optimizer decides to inline it? How many lines may I add to the method before your approach changes? By adding a line, will I speed things up or slow them down? > > To write serious object-oriented software, which at run time will > inevitably generate many objects, some of which may become useless, > one needs a good garbage collector. This is the case in Eiffel > (which uses an incremental, parallel scheme so as not to impair performance). > As far as I know, C++ systems do not support garbage collection, > which would be extremely difficult if not impossible to implement > because of the presence of C types and mechanisms. Obviously, one does not need a good garbage collector if one cleans up after oneself. Having been burned before by garbage collection, I remain wary of claims of efficiency. With C++, I control allocation and deallocation of memory resources explicitly, so I know their performance impact. With Eiffel, do I just trust that you won't collect garbage at an inopportune time, like halfway through emitting a frame? > Compatibility with C means that in C++ you still have pointers, > type casts, pointer arithmetic, function pointers, malloc, free, bizarre > operator precedence (the famous asterisk/parenthesis bugs), > weak type checking and so on. > In Eiffel, the choice has been made. None of these low-level features > are present (as John Sarkela pointed out in a previous message); needless > to say, they are not missed. In analyzing incoming data frames, we freqently encounter the problem of extracting or adding variable-length headers, at various positions in a byte array. It's most convenient (and efficient) to be able to adjust a byte pointer, then reinterpret the pointer as a struct pointer. This may not be "textbook" programming style, but life isn't filled with textbook problems either. The pragmatism of C in these situations is one reason I prefer it to Pascal these days, and why I endure all of C's warts. Yes, I want many of the benefits of Eiffel...but when I need just to get the job done, will I be calling my old C routines because your choices didn't fit? > Learning a new language such as Eiffel is nothing for a > competent programmer. For Eiffel, which is small and simple, > the learning process typically lasts a few days at most. Natch! I learned C in a few days, few being a relative term. Becoming fully versed and competent took a "few" more, and I might still have a couple days to go. You're probably right about being easier to learn than C++, though, not having the forward interference from C to contend with. As someone involved in the selection of an OOP language, I have to say that the decision between C++ and Eiffel isn't a trivial one. Many of the factors are political, since C++ has a large and "grass-roots" support base, while Eiffel is relatively new to the scene, and more academic in its "feel." I think the decision will be influenced strongly by support tools, since successful OOP programming, IMHO, depends on making classes available to a team in an accessible and controllable manner. Eiffel has a solid, but largely proprietary, environment set; C++ seems bogged down in this area, but with many vendors interested. I hope both ISE and AT&T feel some healthy competition between their products, since this will encourage more tool development. These days a language can't be considered realistically outside of its tool environment; this goes double for an OOP language. Larry Morris, Tridom Corporation ...!emory!tridom!lam
aro@aber-cs.UUCP (Andrew Ormsby) (06/06/89)
In article <2689@ssc-vax.UUCP> dmg@ssc-vax.UUCP (David Geary) writes: > I've been programming in C for about 5 years, and >just recently started using C++. I would like to >start a discussion of Eiffel vs. C++. I understand >that both languages use C as a base language, and >that both implement OOP features, and it seems as >though the two have much more in common, aside from >syntactic differences, than they have differences. It is true that current implementations of Eiffel use C as a base language. With Eiffel, however, the use of C is really as a portable assembler that the Eiffel translator can compile into. This has presumably greatly reduced the development costs of the compiler for Interactive Software Engineering, Meyer's firm. There is the added advantage that it enables them to make use of the machine dependent optimisers that are usually part of the C compilation systems on various machines. However, I would contend that the fact that Eiffel uses C as a "base language" is only an implementation detail. C++ is very different. To quote Stroustrup in the introduction to the C++ book, "Except for minor details, C++ is a superset of the C programming language". C++, quite deliberately, therefore ends up looking very much like C. While most current C++ translators are implemented as preprocessors for C compilers, there are a growing number of true C++ compilers. My view is that C++ is what people should be using as an alternative for C in applications where C was really necessary; where there are programmers around who know how to use it properly. My worry is that C++'s additional complexity over and above C will make it even more likely that bad C++ programs are written. Eiffel may be more appropriate as a general purpose language; my personal opinion is that it looks likely to be less easily misused. However, C++ is widely available and cheap. Eiffel is less widely available and rather expensive. Its a shame. >~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >~ David Geary, Boeing Aerospace, Seattle ~ >~ "I wish I lived where it *only* rains 364 days a year" ~ >~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Andy Ormsby, aro@cs.aber.ac.uk Department of Computer Science, aro%cs.aber.ac.uk@nsf-relay.ac.uk University College of Wales, aro%cs.aber.ac.uk@ukacrl.bitnet Aberystwyth, Dyfed, UK, SY23 3BZ.
mgardi@watdcsu.waterloo.edu (M.Gardi - ICR) (06/06/89)
I have heard that eiffel creates hideously large executables from very trivial programs. Does anyone have any information as to whether this is true or not?? I found that using advantage C++ also produced large executables...one of the reason why I am using Zortech C_++ currently. It does not seem to have this problem (executable size seems on average to be about 1/5 the size of advantage c++ code). We're talking 35K here for a hello world program in advantage...something that can't be tolerated on the PC. One source gave the comparable eiffel program a number even much higher. Peter DeVries Mutual Life of Canada (519) 888-2957 c/o mgardi@watdcsu
jwg1@bunny.gte.com (James W. Gish) (06/06/89)
In article <150@eiffel.UUCP> Bertrand Meyer writes: > C++ is obviously very compatible with C. But in Eiffel too you can >easily communicate with C software; both call-in and call-out are >provided. This makes it possible to reuse existing software easily. >The need for such communication was not, however, deemed to be a good >argument for impairing the consistency of the language itself. > I believe this should be qualified somewhat. You indeed can make calls to C routines from Eiffel and vice versa. But life is rarely that simple. You have to map Eiffel objects to C structures and vice versa. This is tedious but can be done in some/most(?) cases. One of the biggest problems that keeps calls from Eiffel to C non-trivial is the inability to use C include files within Eiffel for the definition of types on the Eiffel side. This is a serious obstacle to making use of much C code. A case in point is the use of X. (There are other problems here such as callbacks, but I don't want to go into that here). Much of the X stuff is defined in C header files. To make use of these header files within Eiffel requires either a manual or user-defined automatic translation mechanism. I don't expect miracles here and I don't expect ISE to come up with solutions to the problems generated by C language design sins or the poor coding practice of some C programmers, I just want to point out that the statement "...in Eiffel too you can easily communicate with C software; both call-in and call-out are provided" does not tell the whole story. Also, with respect to reusing existing software easily, it definitely is NOT easy to make use of existing X code, particulary existing widgets. We've made a serious attempt at it and can do it with some success, but it is not fun or easy. And please correct me if I'm wrong, but having the X-based graphics classes will not make it any easier to (re)use existing widget sets either. > >Simplicity and ease of learning > > Much of the plea for C++ is based on the observation that it provides >an easy transition from C, which (for better or worse) is the language >many programmers know nowadays. Using Dr. Brad Cox's expression (meant >for Objective-C), this supports an ``evolutionary'' approach. > > I can certainly respect this view and its appeal to software managers >in industry. But I believe that by considering it more closely one will >find it short-sighted and ill-founded. > > Learning a new language such as Eiffel is nothing for a >competent programmer. For Eiffel, which is small and simple, >the learning process typically lasts a few days at most. >Nobody has ever told us that Eiffel was difficult to learn. >(If you read this, have tried to learn Eiffel, >and found otherwise, please respond!) I believe that the process of >going to Eiffel is in fact much smoother, as you don't have to use >a confusing mix of old and new concepts. >In a language that you master totally, you feel >confident and you can concentrate on your job rather than on >the language intricacies. I agree that learning a new language is nothing for a competent programmer. However to learn to program effectively and efficiently in a new language takes much more than a few days, especially if one is switching paradigms. Learning to use the language fully and understand its subtleties is a long term affair. I have been using Eiffel for several months and still don't feel like an expert - nor did I expect that I would. One of the obstacles to learning is the lack of a comprehensive language reference manual. I was pleased to read that one is forthcoming. Another obstacle, which I believe another poster already stated, is the lack of thorough documentation for the library classes. At times, I have had to write test programs or actually look at the source code for the classes to figure out how to use them. A case in point is the class H_TABLE. I wanted to dump the non-null entries of a an H_TABLE that I created. I thought that I could loop through it using entry(i) with i going from 0 to nb_elements-1. Unfortunately, it wasn't that simple, since entry(i) doesn't return the non-null entries like I expected it would. Better documentation would have prevented me from making this mistake. Examples in the documentation could alleviate some of the confusion. > > Also, the brief initial shock produced by the realization that you >cannot easily write your programs in a traditional way any more is, >in the experience reported by Eiffel users, highly salutary. > But still requires a considerable realignment of ones neurons :-) -- Jim Gish GTE Laboratories, Inc., Waltham, MA CSNET: jgish@gte.com UUCP: ..!harvard!bunny!jwg1
jwg1@bunny.gte.com (James W. Gish) (06/07/89)
The following "Hello world" program generated an executable on a Sun3 of 147456 bytes: class world inherit STD_FILES feature Create is do putstring( "Hello world." ); new_line; end; end The .eiffel file used was: ------------ EIFFEL SYSTEM DESCRIPTION FILE ------------------- -- For simple uses, just replace ``root_class_name'' below -- by the name of the root class of your system (lower case) ROOT: world SOURCE: /usr/proj126/Eiffel/library EXTERNAL: NO_ASSERTION_CHECK (N): PRECONDITIONS (N): ALL_ASSERTIONS (Y): DEBUG (N): TRACE (N): OPTIMIZE (N): GARBAGE_COLLECTION (N) VIRTUAL_MEMORY (N) C_PACKAGE (N): C_EXTERNAL: MAKE: VISIBLE (N): ---------------------------------------------------------------- -- Jim Gish GTE Laboratories, Inc., Waltham, MA CSNET: jgish@gte.com UUCP: ..!harvard!bunny!jwg1
bertrand@eiffel.UUCP (Bertrand Meyer) (06/07/89)
La calunnia: e` un venticello, Un auretta assai gentile che insensibile, sottile incomincia, incomincia susurrar. (The great Calumny aria from the Barber of Seville) I have never had any personal business with Dr. Stroustrup. Any personal hostility is his problem. I let readers judge who is insulting whom. For my part, I have no time to waste on his personal attacks, not a single one of which is true. In my previous message, I stated a fact: Eiffel has been excluded from a projected OOPSLA panel on the design of object-oriented languages. This is in the public record and now confirmed by the party that caused the exclusion. Anyone can judge on the ethics of the situation. ------------------------ Note: I am writing this just before leaving for a 3-week trip and I cannot possibly answer the mail messages that I have received recently. I will try to do so when I come back. I thank all the people who wrote to me. A few of these messages disagreed on some points of my technical note, although in my quick review I didn't find anything that clearly invalidated something I wrote. Several people mentioned that I should have included Turing among the ``commonly available languages'' supporting assertions. I guess I was not aware that Turing was so commonly available in universities. In any case I am happy to correct the omission and to admit that my Turing could benefit from some brushing up. -- -- Bertrand Meyer bertrand@eiffel.com
scs@vax3.iti.org (Steve Simmons) (06/07/89)
Various folks have talked about the sizes of linked eiffel and c++ programs. It all sounds very much like the debate of using or not using stdio because of the size overhead. For more built-in features and libraries, we must pay a price. [[insert comment about "the more things change...." here]] Steve Simmons Just another midwestern boy scs@vax3.iti.org -- or -- ...!sharkey!itivax!scs "Think of c++ as an object-oriented assembler..."
donahn@gypsum.berkeley.edu (Don Ahn) (06/08/89)
In article <5975@watdcsu.waterloo.edu> mgardi@watdcsu.waterloo.edu (M.Gardi - ICR) writes: > >I have heard that eiffel creates hideously large executables from very >trivial programs. Does anyone have any information as to whether this is >true or not?? I found that using advantage C++ also produced large >executables...one of the reason why I am using Zortech C_++ currently. It does >not seem to have this problem (executable size seems on average to be about >1/5 the size of advantage c++ code). >We're talking 35K here for a hello world program in advantage...something >that can't be tolerated on the PC. One source gave the comparable eiffel >program a number even much higher. What I'd be more interested in here is the INCREMENTAL increase in executable size due to program lines/functionality. Given the fact that eiffel has more functionality in it's run-time environment (built in garbage collection etc..) it is understandable that for "trivial" programs code size will seem to be unexplainably huge. This is not to say that the code size for a "hello, world\n" program is not completely unimportant. A extremely large amount of code for a "trivial" program may indicate an inefficient linker. But it does not necessary mean that the compiler is a dog. A more meaningful comparison to me would be the executable size of two large "algorithmically equivalent" programs. Given the power that an OOPS gives you, re-useable and organized code, it may be possible to DECREASE your executable size over a non-OOPS language for large programs. Of course, a well implemented program in a lower-level language (C , assembler) will always be more efficient than an OOPS. The problem is, it gets exponentially harder to create a "well implemented" program as its size goes up in a low level language. As I see it, OOPS was created to help make LARGE programs maintainable. The merits of an OOPS should be measured in this realm.
jos@cs.vu.nl (Jos Warmer) (06/08/89)
In article <JWG1.89Jun6172452@bunny.gte.com> jwg1@bunny.gte.com (James W. Gish) writes: > >The following "Hello world" program generated an executable on a Sun3 >of 147456 bytes: [... removed ...] >The .eiffel file used was: > >ALL_ASSERTIONS (Y): >C_PACKAGE (N): The size of executables in Eiffel depends very much on the compile options. The smallest size will be reached when all assertions are turned off. And all optimizations like inline functions and others are only done when generating a C package. Using: ALL_ASSERTIONS(N): ALL C_PACKAGE (Y): C gives an executable of 73728 bytes. Using `strip world' gives 57344 bytes. (Eiffel Version 2.1b, SUN3.5) Besides, I do agree with Don Ahn: In article <25321@agate.BERKELEY.EDU> donahn@gypsum.berkeley.edu (Don Ahn) writes: > >What I'd be more interested in here is the INCREMENTAL increase in executable >size due to program lines/functionality. Given the fact that eiffel has more >functionality in it's run-time environment (built in garbage collection etc..) >it is understandable that for "trivial" programs code size will seem to be >unexplainably huge. ... Jos Warmer jos@cs.vu.nl ...uunet!mcvax!cs.vu.nl!jos -- Jos Warmer jos@cs.vu.nl ...uunet!mcvax!cs.vu.nl!jos
marc@eiffel.UUCP (Jean-Marc Nerson) (06/09/89)
>The following "Hello world" program generated an executable on a Sun3 >of 147456 bytes: > >class world >inherit > STD_FILES >feature > >Create is > do > putstring( "Hello world." ); new_line; > end; >end > The same "Hello world" program compiled with Eiffel version 2.2-ALPHA, post-processed and all optimizations turned on, generates an executable of 64671 bytes (53248 bytes stripped) on a Sun386i running O.S 4.0.1 where C libraries are dynamically linked. On a Sun3 O.S 3.5 with non dynamically linked C libraries, the size of the generated code is 73728 bytes (57344 stripped). The same "Hello world" program written in C on a the Sun386i O.S 4.0.1 is 8645 bytes (4408 bytes stripped) and on the Sun3 O.S 3.5 it is 32768 bytes (24576 bytes stripped). Eiffel run-time libraries are currently not dynamically linked (this might be in Eiffel 3.0). Jean-Marc Nerson -- marc@eiffel.com
jans@tekgvs.LABS.TEK.COM (Jan Steinman) (06/09/89)
<mgardi@watdcsu.waterloo.edu (M.Gardi - ICR)> <A more meaningful comparison to me would be the executable size of two large "algorithmically equivalent" programs.> We have an application that is implemented in both Smalltalk and C++/Interviews/X11. When compiled with debugging on, the C++ version is much slower and nearly as large as the whole Smalltalk image, which contains much more functionality, and always has debugging available. This is not meant to start any kind of war, simply to point out than many comparisons of the sort compare apples with oranges. With debugging off, the C++ version is about 1/6 the size of the whole Smalltalk image, although graphics performance is still slower -- probably due to the many layers of software needed, while Smalltalk is able to BitBlt. :::::: Jan Steinman - N7JDB Electronic Systems Laboratory :::::: :::::: jans@tekgvs.LABS.TEK.COM Box 500, MS 50-370 (w)503/627-5881 :::::: :::::: jsteinma@caip.RUTGERS.EDU Beaverton, OR 97077 (h)503/657-7703 ::::::
plogan@mntgfx.mentor.com (Patrick Logan) (06/09/89)
In article <1989Jun6.171549.16028@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes: :) In article <233@pink.ACA.MCC.COM> rfg@pink.aca.mcc.com.UUCP (Ron Guilmette) writes: :) >For me, Eiffel was kind of like a chastity belt. It definitely keeps :) >you "pure" but you will probably have less fun. :-) :) :) It struck me, in fact, that a good many of Dr. Meyer's comparisons between :) C++ and Eiffel boiled down to "C++ lets the programmer foul things up in :) any way he pleases, while Eiffel insists on doing it right". This is, in :) fact, a long-standing philosophical difference between the C camp and the :) Pascal camp. Instead of the phrase "doing it right" I think it would be more fair to paraphrase with "doing it according to some principles of sound software construction." As I read it, the phrase "doing it right" carries more self-righteousness than I felt existed in the original article. The article mentioned or referred to the guiding principles. :) The Pascal side favors using the language to impose discipline, which makes it :) a LOT easier to get reliable, well-behaved programs but can make it harder :) to get the desired results with those programs. Which set of tradeoffs is :) better depends on the circumstances and the people. :) :) (Me? I find the Pascal theory very attractive but at the moment am fully :) in the C camp for pragmatic reasons. Combining the virtues of the two :) ought not to be impossible but seems to be difficult in practice. Perhaps :) a mixed approach is better than trying to pick one or the other.) :) -- :) You *can* understand sendmail, | Henry Spencer at U of Toronto Zoology :) but it's not worth it. -Collyer| uunet!attcan!utzoo!henry henry@zoo.toronto.edu The logic here seems to be the following: The argument of C++ vs. Eiffel is similar to the typical C vs. Pascal argument. Therefore Eiffel is in the Pascal "camp". Therefore Eiffel will have the same problems as Pascal. I wouldn't consider this sound logic. Its application could lead someone away from even attempting to evaluate Eiffel. -- Patrick Logan | ...!{decwrl,sequent,tessi}!mntgfx!plogan Mentor Graphics Corporation | plogan@pdx.MENTOR.COM Beaverton, Oregon | "My other computer is a Lisp machine."
bs@alice.UUCP (Bjarne Stroustrup) (06/10/89)
I stated in an earlier message that I was unwilling to share a stage with Bertrand Meyer because of his grossly impolite and insulting behavior toward me, my friends, and professional colleagues. He replied that my claims are groundless. Clearly we cannot both be telling the truth. Many people who attended ECOOP'87, and some who attended OOPSLA '88, are in a position to know for themselves which of us is lying. Others can read this whole distasteful series of exchanges starting with Bertrand Meyer's original posting and make a guess. Bertrand Meyer's company's use of AT&T's name and quotes from my copyrighted works in its advertising (without permission, of course) is also available for all to see. The present exchange is in itself a good example of why I prefer to have as little as possible to do with Bertrand Meyer. He has too often failed to attain the minimal standards of common courtesy and detachment from commercial concerns necessary for a technical exchange. For example, `part two' of his technical comparison of C++ and Eiffel contained a litany of unfounded accusations using extreemely loaded vocabulary: `censorship, money, power, intimidation, hype, one-sided propaganda, scared indeed, suppressed, pre-settled panels, biased articles, trying to crush.' - Bjarne Stroustrup PS By replying to his postings I did enter into a public discussion with Bertrand Meyer. That was probably a mistake, but I considered it a very real danger that unanswered accusations could become accepted `fact.'
bigm@batserver.cs.uq.oz (Michael Pilling [Real people drink purple milk]) (06/11/89)
Larry Morris in a recent article writes > > can talk about the very idea of reusable software components without > > assertions... > > maintained by the amplifier). Yet of widely available programming > > languages, only Eiffel has these notions. > Assertion checkers, of course, have been used for years as tools outside > the scope of the language, as libraries, or extracted by tools from > code comments. Placing assertions within classes as part of the language > is, I must agree, a very powerful feature. But Eiffel's design philosophy > calls on programmers to define their classes with assertions in addition > to coding their implementation; something most programmers aren't used to > doing and may view as an onerous task. Since assertion checking isn't any > better than the assertions dreamed up by the programmer, I'm skeptical of > using it to "replace" unit testing. I have been encouraging my group software project students to use assertions, and have found that they take some time to get into the swing of writing effective and prudent assertions. This feeling is based on their reactions, I have yet to mark their code (uggggh). Like anything there is a learning curve and a few people will never really get the hang of it. This is not to say assertions are a bad feature, it mearly reveals those who should should be programming and those whose talents lie in other areas. (Perhaps they could help me with my spelling :-) ) I have been using assertions for 3 years and felt obliged to point out that they are not intended to "replace" unit testing but to simplify and augment it. I have found assertions to have the following benifits in whatever language you choose to implement them. 1. Carefully chosen assertions clarify your understanding of the code you are writing or reading and force you to reason about what you are really doing and it's consequences. I have found this to be the most important benifit. It allows you to produce clearer, simpler and more efficient CORRECT code. 2. Error detection is increased. You can't fix them if you don't find them. In a large library module, certain code may never be executed until it fails. This may be 2 or 5 years down the track. Or the error may not manifest 99% of the time because one errornous result in a record/structure is only occasionally accessed. Assertions add another layer of testing - those of self consistency and plausability e.g.s While traversing a doubly linked list you can assert that the current link points back to where you came from. A positive square root should be smaller than the input and when squared should give the input. 3. Errors are detected close to their occurence in space and time. Symptoms of the error may be much further away when the real causes have been obscured. This makes fixing the bug easier because you don't have to waste so much time looking for it. e.g. Space - Assertions fail in your binary search routine - jumping to the bottom half of the array actually gave you a smaller key!! Conclusion: The caller lied when they claimed the array was sorted. Saved from wasting time trying to debug the correct binary search routine. Time - Stange errors are occurring in your program. You suspect the memory arena's been trashed but have no idea who did it and when. Assertions can often detect the culprit soon after they commit the crime. 4. When you think you've fixed the bug the saftey net is still there to tell you you were wrong. In libraries this to can be useful to detect bugs in infrequently used code rather than letting them slip through unnoticed. 5. They can make programs more robust and protect data by stopping their progress in emergancy situations. Real Life example: Data General AOS/VS operating system utility "Exec" hung itself after uttering: Internal inconsistancy error - negative time encountered. In reality, one of the sysops had corrected the time of day because it was fast. Exec caught itself completing a task before it started and thought the clock hardware had failed. It correctly aborted system processing rather than risk damaging timestamps used for backups and other data consistancy functions. 6. You can avoid buggarising your code with error handlers. Why should you attempt to clean up other peoples mistakes. Your code is simpler and more likely to be correct. eg When I did the group software project I was the only one to use assertions. During intergration, people would run to me saying YOUR module had ANOTHER assertion failure. More often than not, I had the pleasure of replying "Oh, that means your not sorting that array you passed me like you were supposed to." I have personally found the use of assertions to save me 80% of my previous debugging time and effort. They allow you to tackle problems that would be almost insumountable otherwise, particularly when useing malloc & free. Like any good investment they pay many returns over a long period. Assertions should be included in the language (definition and compiler proper) so you can turn them off (at your own risk). Preprocessed assertions often produce much more code per assertion and can not check that your assertions do not have side effects. (Side effects prevent you from turning them off because you program behaves differently.) Michael Pilling, Computer Science Department, University of Queensland, St Lucia, 4067 Australia.
ark@alice.UUCP (Andrew Koenig) (06/12/89)
In article <807@batserver.cs.uq.oz>, bigm@batserver.cs.uq.oz (Michael Pilling [Real people drink purple milk]) writes: > A positive square root should be smaller than the input and > when squared should give the input. Sometimes the code is right and the assertion is wrong. For example, sqrt(0.25) should be 0.5 -- --Andrew Koenig ark@europa.att.com
dan@oresoft.uu.net (Daniel Elbaum) (06/13/89)
Gee, this discussion reminds me--C is really a much better programming language than Pascal. You all agree, don't you? -- The workaday world must remain transparent to those who maintain it if they are to find inspired within them a vision of the history they create. ({uunet,tektronix,reed,sun!nosun,osu-cis,psu-cs}!oresoft!(dan)@oresoft.uu.net)
db@lfcs.ed.ac.uk (Dave Berry) (06/13/89)
In article <150@eiffel.UUCP> bertrand@eiffel.UUCP (Bertrand Meyer) writes: > C++ has a notion of friend function which, as I understand it, makes >it possible to define routines outside of the object-oriented framework. >There is nothing equivalent in Eiffel. This facility is not missed. In C++ a class A may define other classes to be its friends; these classes can access all attributes and members of A. From the book (OOSC), Eiffel does seem to have an equivalent, namely the facility where members may be exported to certain named classes only. Both mechanisms allow A to control access to part of itself. The Eiffel mechanism gives finer control. I don't know if this finer control will matter in practice. Friend functions in C++ are similar, but allow the integration of object oriented software with non-OO software, in keeping with the rest of the language. >Compatibility with C means that in C++ you still have pointers, type casts, >pointer arithmetic, function pointers, malloc, free. I strongly disagree >with this approach if the goal is to obtain software quality. In Eiffel, >the choice has been made. None of these low-level features are present; >needless to say, they are not missed. Except by all the people asking for them on USENET ( semi :-) ). I would say that languages don't encourage software quality if they require the use of low-level features unnecessarily. C & C++ undoubtably do so, although C++ will improve when type parameterisation and multiple inheritance are available. This doesn't mean that such features should not be provided. Sometimes some people need low-level control. What is important is that they should be able to hide their use of such features from the rest of the program. I find it odd that Meyer considers function pointers "low-level". There was some discussion of function parameters in Eiffel a couple of months ago, and they seemed to offer neater solutions (IMAO) to some problems than the alternative techniques. Treating functions as first order objects (or "nearly firat order" objects) is usually considered high level. Dave Berry, Laboratory for Foundations db%lfcs.ed.ac.uk@nsfnet-relay.ac.uk of Computer Science, Edinburgh Uni. <Atlantic Ocean>!mcvax!ukc!lfcs!db Britain without the Queen is like a democracy without a monarch.
geof@nswitgould.OZ (Geoffrey Jones) (06/14/89)
In article <11991@nswitgould.OZ>, I wrote: > As a small issue in C++'s favour, each C++ class > can contain a destructor routine which is executed whenever an object > of that class is destroyed, which will be whenever the object goes out > of scope (e.g., at program termination) or whenever it is actively > deallocated from the dynamic memory pool. No such operation exists in > Eiffel. This makes certain types of programming awkward in the latter. Oh dear, searching through my comp.lang.eiffel archive I grepped on "destructor" and found to my surprise that Jos Warmer (jos@cs.vu.nl) had already raised this point in article <2152@vlot.cs.vu.nl>. I'll include a little of it here because the article has probably expired from most sites by now and many comp.lang.c++ people following this discussion won't have read it before: > Some problems with garbage collection: > > 1. In the library class FILE one can create a FILE object, open it and use it. > If the FILE object is not referenced anymore, the memory used by it > will be reclaimed by the garbage collector. > However, each file that is opened should be closed before the FILE object > is destroyed. > > This can not be forced by the FILE class, but it is left to the client. > It should be much safer if the FILE class could ensure that each file > is closed before the object pointing to it is destroyed. > [ ... much more removed ... ] > > A possible solution: > > In C++ so-called destructors can be defined. A destructor is a routine > that is called on an object when the object is being freed. > A destructor contains code that performs some cleanup before the object > is destroyed. > > These destructors can be used to solve the problems described above. > I cannot find a way to solve these problems in eiffel. Should such > a feature be added eiffel, or are there other solutions. In article <129@eiffel.UUCP> Bertrand Meyer (bertrand@eiffel.UUCP) follows up to provide a (patch) solution: > In version 2.2 the library class MEMORY will include an argumentless > procedure called dispose, to be invoked by the garbage collector (if > active) when an object is freed. The original version of this class > has an empty body and hence does nothing. Any class can inherit > from MEMORY and redefine this procedure to do something, for instance > close a file as in Mr. Warmer's example. > > Two caveats: > > - The exact details are still subject to change. > > - The next version (Eiffel 3, end of 1989) will support the > possibility of treating all objects as persistent (the set of all > objects of an Eiffel session becoming a database). In this context > the problem addressed by Mr. Warmer becomes part of a larger > requirement (describing what should be done to any object when > the session terminates, or when it is stored to a file by an automatic > mechanism). This means that the 2.2 solution may be overridden at that > time by a more general scheme. The version 2.2 solution is indeed a step in the right direction but I don't see that it should be the final answer. An "obvious" solution might be to imbue Eiffel's `Forget' with an enlarged semantics, thus moving the solution under the auspices of the language definition and away from all the ad hoccery involving strange class inheritences. I would propose that programmers could define their own `Forget' routines analogously to programmer-defined `Create's. Thus the responsibility to call server class terminating routines (e.g., `close' in class FILE) would be removed from the server's clients (as Dr Meyer's v2.2 solution seems to allow), as well as from the vagaries of the garbage collector which may or may not be active depending on all sorts of contingencies not the least of which is whether the GC was enabled at compile-time(!). I believe it would be proper if each class instance had its programmer-defined Forget routine called whenever that instance went out of scope of all other system objects, i.e., if a successful garbage sweep of the object could be made or whenever the program was terminating. Naturally these are only tentative thoughts which should be weighed in the light of added language complexity and so forth. However the problem of proper object termination is a real one that must be addressed in the not-too-distant future if Eiffel is to become a suitable platform for many types of computing tasks. Geof. ---------------------------------------------------------------------------- Geoffrey Jones ACSnet: geof@nswitgould.oz.AU Dept. of Computer Science ARPA: geof%nswitgould.oz.AU@uunet.UU.NET U. of Technology, Sydney UUCP: ...!munnari!nswitgould.oz.AU!geof P.O. Box 123, Or try: munnari!nswitgould.oz.AU!geof@uunet.UU.NET Broadway, 2007 AUSTRALIA Phone: (02) 218 9505 ----------------------------------------------------------------------------
diamond@diamond.csl.sony.junet (Norman Diamond) (06/14/89)
In article <807@batserver.cs.uq.oz>, bigm@batserver.cs.uq.oz (Michael Pilling [Real people drink purple milk]) drank something purple that wasn't just milk: >> A positive square root should be smaller than the input and >> when squared should give the input. In article <9464@alice.UUCP> ark@alice.UUCP (Andrew Koenig) writes: >Sometimes the code is right and the assertion is wrong. >For example, sqrt(0.25) should be 0.5 This is entirely correct, of course. Nonetheless, suitable use of assertions make it much easier to debug both the assertions and the code, than it is to debug code by itself. -- Norman Diamond, Sony Computer Science Lab (diamond%csl.sony.co.jp@relay.cs.net) The above opinions are my own. However, if you see this at Waterloo, Stanford, or Anterior, then their administrators must have approved of these opinions.
rpj@mcc.com (Rich Johns) (06/14/89)
With debugging off, the [C++/InterViews/X11] version is about 1/6 the size of the whole Smalltalk image, although graphics performance is still slower -- probably due to the many layers of software needed, while Smalltalk is able to BitBlt. What X11 server are you using? If its on a sun3, for example, I can see why the performance is slow. Also, I believe that InterViews 2.5 has BitBlt capability. Rich Johns, MCC CAD Program | 3500 W. Balcones Center Dr., Austin, TX 78759 ARPA: johns@mcc.com | Phone: [512] 338-3714 UUCP: {uunet,harvard,gatech,pyramid}!cs.utexas.edu!milano!cadillac!johns
mjl@cs.rit.edu (06/15/89)
In article <9456@alice.UUCP> bs@alice.UUCP (Bjarne Stroustrup) writes: >Bertrand Meyer's company's use of >AT&T's name and quotes from my copyrighted works in its advertising >(without permission, of course) is also available for all to see. I don't want to get bogged down in the name calling and other vituperative rantings and ravings that have been going on in these newsgroups, but this sentence intimates that ISE and Dr. Meyer have done something improper with Dr. Stroustrup's work and AT&T's name. I assume Dr. Stroustrup refers to ads such as the one in the July 1988 issue of IEEE Software (inside the front cover). If so, then two points must be made: 1. Three of the four quotes refer to an article by Dr. Stroustrup in IEEE Software, and, as a member of the editorial board, I know that the copyright belongs to the IEEE (this is standard policy). 2. All of the quotes are short, and properly cited in the ad. As such, they are covered by the fair use doctrine, and ISE has done nothing improper in using them. I'll leave it to others to determine whether or not the quotations were used out of context. 3. The only reference to AT&T is in a footnote attached to a table comparing C++ to Eiffel, and simply is used to document the version of the C++ compiler used in the comparisons. Rather than slandering AT&T, this provides a service to readers of the ad. In short, there seems to be little basis for this particular complaint. Mike Lutz Rochester Institute of Technology, Rochester NY UUCP: {rutgers,cornell}!rochester!ritcv!mjl CSNET: mjl%rit@relay.cs.net INTERNET: mjl@cs.rit.edu
jeff@aiai.uucp (Jeff Dalton) (06/19/89)
In article <150@eiffel.UUCP> bertrand@eiffel.UUCP (Bertrand Meyer) writes: >From article <2689@ssc-vax.UUCP> by dmg@ssc-vax.UUCP (David Geary): >Eiffel software is organized in autonomous software units (classes), >meant to be compiled separately. There is no main program. [...] In >contrast, I understand that C++ still follows the traditional C model. >[...] ``A C++ program typically consists of many source files, each >containing a sequence of declarations of types, functions, variables, >and constants''. This is very far from the object-oriented model of >software decomposition. It is true that C++ does not enforce object-oriented decomposition or provide explicit support for it. Nonetheless, a C++ programming environment could provide such support. And it is possible to make reasonable decompositions in C and C++, even though the compilation units are files, and even without any special environmental support that "hides the files". So I don't think C++ prevents the programmer from doing objet-oriented decomposition, but I'll have to leave the details to those who know more about C++ than I do. >Multiple inheritance > > Multiple inheritance is fundamental in the Eiffel approach. We made >every effort to handle it in a very clean way; name clashes, in particular, >are treated in what I believe is the right way. (More precisely, I do not >know of any satisfactory solution in any other language. This is a strong >statement, and proponents of other languages are welcome to respond to the >challenge.) I think the statement is too strong as it stands, because "satisfactory" isn't defined. It also makes it difficult for other languages to respond to the challenge. But I'm not sure it's possible to make strong conclusions in any case. Suppose someone said the Eiffel solution was unsatisfactory. How could this be resolved? IN the end you may just have different goals. >Garbage collection >As far as I know, C++ systems do not support garbage collection, >which would be extremely difficult if not impossible to implement >because of the presence of C types and mechanisms. As far as I know, it is possible to provide garbage collection for C, and some systems have actually done so. The GC has to be "conservative" in that it must regard anything that might be a pointer as a pointer. So there might be some garbage it can't collect, but it will never collect non-garbage. It is possible to write some things in C that will cause such systems to go wrong, but (again, as far as I know), all such things are regarded as nonportable. So conforming programs can't do them. -- Jeff
jeff@aiai.uucp (Jeff Dalton) (06/19/89)
In article <89155.092349UH2@PSUVM> UH2@PSUVM.BITNET (Lee Sailer) writes: >the address, and thus cannot optimize well. The same argument has >been made about strings---C does NOT have a string type. We fake it >with pointers (addresses) and arrays (pointers 8-). In a language >that does have a specific string data type, the compiler writer has >a chance to do some optimization tricks otherwise not available. I think this may be a more complex issue than it at first appears. Richard O'Keefe has argued on several occasions that string processing is more efficient when there isn't a built-in string type. I'm not sure he's correct, but he generally knows what he's talking about. (I'm sorry I don't have any "real" references -- there were just some articles in Comp.lang.c (I think) and Comp.lang.prolog.)
jimp@asterix.UUCP (Jim Patterson) (06/24/89)
In article <12031@nswitgould.OZ> geof@nswitgould.OZ (Geoffrey Jones) writes: >In article <129@eiffel.UUCP> Bertrand Meyer (bertrand@eiffel.UUCP) >follows up to provide a (patch) solution: > >> In version 2.2 the library class MEMORY will include an argumentless >> procedure called dispose, to be invoked by the garbage collector (if >> active) when an object is freed. > >The version 2.2 solution is indeed a step in the right direction but I >don't see that it should be the final answer. An "obvious" solution >might be to imbue Eiffel's `Forget' with an enlarged semantics, thus >moving the solution under the auspices of the language definition and >away from all the ad hoccery involving strange class inheritences. I >would propose that programmers could define their own `Forget' >routines analogously to programmer-defined `Create's. This suggestion ignores the significant difference between Eiffel's Forget builtin feature and more direct memory management primitives such as C's free. Forget simply clears a reference to an object; it's still left up to the garbage collector to actually free the object, and then only if there are not other references. If Forget were changed to actually dispose of the object (or to perform cleanup code), then other references to that object within the program would suddenly became invalid. This negates the major benefit of a garbage collector, which is to relieve the programmer of the burden of tracking which objects are or are not still accessable. Dispose is the more appropriate solution, as it supports an arbitrary number of references to any object so that the Dispose procedure is only actually called when there are no remaining references. One drawback is that the actual timing of a Dispose call is somewhat arbitrary; this must be considered when designing the class. -- Jim Patterson Cognos Incorporated UUCP:decvax!utzoo!dciem!nrcaer!cognos!jimp P.O. BOX 9707 PHONE:(613)738-1440 3755 Riverside Drive Ottawa, Ont K1G 3Z4
bertrand@eiffel.UUCP (Bertrand Meyer) (06/29/89)
From <233@pink.ACA.MCC.COM> rfg@pink.aca.mcc.com.UUCP (Ron Guilmette), quoted by later messages: >> For me, Eiffel was kind of like a chastity belt. It definitely keeps >> you "pure" but you will probably have less fun. >> It struck me, in fact, that a good many of [B. Meyer]'s comparisons between >> C++ and Eiffel boiled down to "C++ lets the programmer foul things up in >> any way he pleases, while Eiffel insists on doing it right". This is, in >> fact, a long-standing philosophical difference between the C camp and the >> Pascal camp. The debate, which is older and broader than the question of C versus Pascal, is indeed an important one: How restrictive and prescriptive may a language designer be in forcing a particular approach to software construction upon the users of the language? However their application to the design of Eiffel may be judged, I can at least clarify my intentions. 1. ``Chastity belts'' are inappropriate. A chastity belt prevents its holder from doing things that are desirable and enjoyable. A language designer is not a guardian of moral order. 2. A good programming language is one that helps programmers write good programs. No programming language will prevent its users from writing bad programs. [If I recall correctly, this is an observation I first heard a long time ago from Kees Koster, who among other things is the designer of the CDL language.] 3. Some constructs are known to be dangerous, meaning that programs employing them are prone to contain damaging errors. In any language meant for industrial production, it is the language designer's responsibility to exclude such constructs. Examples include type casts, user-controlled memory deallocation, pointer arithmetic, in-line functions (in an object-oriented language) etc. 4. The purpose of excluding a construct is not to prevent programmers from writing bad programs or doing ``dangerous things'' if they want to. (See points 1 and 2.) Instead, a construct is excluded because it is known to lead programmers to make mistakes even when applied towards legitimate goals. This highlights the basis for all this discussion. In the same way that the author of a novel has a typical reader in mind, the designer of a programming language is, consciously or not, designing for a typical programmer. We should assume (as was done for Eiffel) that this typical programmer is intelligent and reasonable. The restrictive parts of the language design are not meant to prevent the programmer from being ``bad'', but rather to help him avoid known pitfalls and involuntary mistakes. 5. For the language designer, excluding a construct is not a solution but a problem. In all likelihood the excluded construct addressed some legitimate need, albeit in an inadequate way. The designer must find a better technique to satisfy the same need. This is the difficult part, of course: exclusion is easy. Sometimes the solution is a better programming language construct; in other cases the problem is best handled by the implementation (compiler and programming environment). For example, unrestrained type casts may be replaced by inheritance-controlled polymorphism; garbage collection should be under the control of the run-time system; pointer arithmetic is unneeded in the presence of type-safe dynamic binding; and in-line routine expansion should be the responsibility of an optimizing compiler. 6. Literal compatibility with previous languages should not be a criterion. People will learn a new language quickly if its design is simple and consistent. One should learn from the mistakes of the past, not perpetuate them. Some care should be exercised, however, when one deals with programmers' current habits. For example, a new language should not use an existing notation in a way that confusingly departs from its accepted semantics. (The Eiffel assignment operator, :=, is a case in point; its semantics would probably have been different were it not for the fear of confusing Algol-Pascal-Ada programmers.) 7. Perhaps my major personal guideline is to maximize the signal-to-noise ratio of the language. Exclude constructs that just add complexity to the language without bringing any significant new possibility (for example, varieties of loops); include constructs that tersely and elegantly address a large number of practical situations. 8. Any occurrence in a language description of a sentence of the form ``Be careful when using this construct'' implying that its use may have dangerous consequences, is an avowal of failure on the designer's part. Programmers should be encouraged to use the entire language, not a subset. The programming language is the software developers' fundamental tool. They should know, love and trust all of it. 9. Hard as you try to maximize the signal-to-noise ratio, there may remain cases in which special needs require special facilities. Such special facilities should be limited to only one situation: the need to access low-level internal or machine-dependent elements. In my opinion, this is best addressed by techniques that fall outside of the language proper, such as machine-code insertions in Ada or external routines in Eiffel. To avoid violating the previous criterion (8), there should be very few such techniques, and they should never be needed in normal uses of the language. In Eiffel their typical uses have been encapsulated in the library (essentially in the class called INTERNAL) and their application is limited to the following cases: - Interfacing with elements on which the language design has no control: existing software tools (for example, relational data base management systems) or software written in other languages. - Machine-dependent programming. - Implementation of facilities which are part of the basic environment (such as the ARRAY and STRING classes in the kernel Eiffel library). - Facilities which the language designer feels are not necessary, while recognizing that some language users may disagree on this point. There is one example of this in Eiffel: class INTERNAL contains a procedure ``free'' which will explicitly return an object to the free store. In our opinion it should never be used, and none of our own software ever uses it; however we accept that some users may disagree and would rather provide the corresponding facility in an ``official'' form than encourage these users to fool around with internal formats. *** In summary, the aim of what Mr. Guilmette calls a more ``pure'' design is not to prevent programmers from ``fouling things up'' but to enable them to do things in a way that is at the same time safer, more elegant, more powerful and more convenient. Reconciling these goals is the main challenge in designing a better programming language. Coming back to the first two lines of his extract: >> For me, Eiffel was kind of like a chastity belt. It definitely keeps >> you "pure" but you will probably have less fun. Eiffel programmers can have fun, too, thank you. Of course, someone whose idea of fun is to spend his or her nights debugging will have less of it. But then such a person wouldn't need a chastity belt anyway. -- Bertrand Meyer bertrand@eiffel.com
nevin1@cbnewsc.ATT.COM (nevin.j.liber) (07/06/89)
Disclaimer: these are my PERSONAL opinions, period. I agree with some of the points; I am mainly commenting on those I disagree with. In article <166@eiffel.UUCP> bertrand@eiffel.UUCP (Bertrand Meyer) writes: |3. Some constructs are known to be dangerous, meaning that programs |employing them are prone to contain damaging errors. |In any language meant for industrial production, it is the language |designer's responsibility to exclude such constructs. | Examples include type casts, user-controlled memory deallocation, |pointer arithmetic, in-line functions (in an object-oriented language) |etc. Unfortunately, stuff like type casts and user-controlled memory management tend to be useful in many contexts. |4. The purpose of excluding a construct is not to prevent |programmers from writing bad programs or doing ``dangerous things'' if |they want to. (See points 1 and 2.) Instead, a construct is excluded |because it is known to lead programmers to make mistakes even when |applied towards legitimate goals. But, as a USER, I really don't care what the *purpose* behind doing something is. For example, the *purpose* behind putting in ramps in sidewalks wasn't to allow kids to ride their bicycles into traffic without having to stop like they had to for curbs, yet that was the *result*. |The restrictive parts of the language design are not meant to prevent |the programmer from being ``bad'', but rather to help him avoid |known pitfalls and involuntary mistakes. But they DO prevent the programmer from being ``bad''; that is the price that is being paid in order to help him avoid known pitfalls and involuntary mistakes. |6. Literal compatibility with previous languages should not be a |criterion. People will learn a new language quickly if its design is |simple and consistent. One should learn from the mistakes of the past, not |perpetuate them. | Some care should be exercised, however, when one deals with programmers' |current habits. For example, a new language should not use an existing |notation in a way that confusingly departs from its accepted semantics. |(The Eiffel assignment operator, :=, is a case in point; |its semantics would probably have been different were it not for the fear |of confusing Algol-Pascal-Ada programmers.) Keeping 6 in mind, and assuming that you wanted to give the Eiffel assignment operator different semantics than those given by Algol/Pascal/Ada to ":=", why didn't you just pick another symbol (eg: ".=")? Please elaborate. |7. Perhaps my major personal guideline is to maximize the signal-to-noise |ratio of the language. | Exclude constructs that just add complexity to the language without |bringing any significant new possibility (for example, varieties of |loops); include constructs that tersely and elegantly address a large number |of practical situations. But varieties of loops, if used correctly (admittedly, a big if), can add to the self-documenting aspect of a language. This whole discussion reminds me of an early paper by Wirth which I read a while back (I wish I could find that paper :-(). In it, he spends the first half describing his ideal programming language, which, to me, seemed close to C, and then spent the second half saying that it was unusable because you couldn't guarantee safety. -- NEVIN ":-)" LIBER AT&T Bell Laboratories nevin1@ihlpb.ATT.COM (312) 979-4751
bertrand@eiffel.UUCP (Bertrand Meyer) (07/07/89)
From <1559@cbnewsc.ATT.COM> by nevin1@cbnewsc.ATT.COM (nevin.j.liber): [Quoting from my previous message: ] > | Some care should be exercised, however, when one deals with programmers' > |current habits. For example, a new language should not use an existing > |notation in a way that confusingly departs from its accepted semantics. > |(The Eiffel assignment operator, :=, is a case in point; > |its semantics would probably have been different were it not for the fear > |of confusing Algol-Pascal-Ada programmers.) > [...] Assuming that you wanted to give the Eiffel > assignment operator different semantics than those given by > Algol/Pascal/Ada to ":=", why didn't you just pick another symbol (eg: > ".=")? Please elaborate. [Perhaps :-) would do for assignment?] :-) Actually the Eiffel convention is the same as the Pascal and Ada ones for entities of pointer/access/reference types, which is the reason for keeping the same notation. In general it seems proper to avoid inventing a new notation where there is no real semantic innovation and a widely accepted notation exists, unless there are strong arguments against that notation. (An example of the latter would be the Fortran/C use of = for assignment, which conflicts with time-honored mathematical conventions.) The language should look familiar in places where the concepts are indeed familiar. There are a number of novel ideas in Eiffel, but assignment is a quite standard concept. As one may expect, the properties of assignment in Eiffel are not identical to those of its counterparts in previous languages, but the differences do not seem big enough to warrant a totally new notation. Call it lack of courage if you will. -- Bertrand Meyer bertrand@eiffel.com
pcg@thor.cs.aber.ac.uk (Piercarlo Grandi) (07/09/89)
In article <168@eiffel.UUCP> bertrand@eiffel.UUCP (Bertrand Meyer) writes: From <1559@cbnewsc.ATT.COM> by nevin1@cbnewsc.ATT.COM (nevin.j.liber): > [...] Assuming that you wanted to give the Eiffel > assignment operator different semantics than those given by > Algol/Pascal/Ada to ":=", why didn't you just pick another symbol (eg: > ".=")? Please elaborate. [Perhaps :-) would do for assignment?] :-) Remember this line for later on... Actually the Eiffel convention is the same as the Pascal and Ada ones for entities of pointer/access/reference types, which is the reason for keeping the same notation. Ugh. I beg to differ. Pascal and Ada have a concept of pointer, and indeed := is used by them to do *copy* of pointer objects. This is VERY different from Eiffel. The analogy cannot hold. In general it seems proper to avoid inventing a new notation where there is no real semantic innovation and a widely accepted notation exists, unless there are strong arguments against that notation. Eiffel, by doing without a concept of pointer (except by hack) and by having reference and copy assignments both under := blurs the distinction between EQ and EQUAL, that lispers know as being very fundamental. As one may expect, the properties of assignment in Eiffel are not identical to those of its counterparts in previous languages, but the differences do not seem big enough to warrant a totally new notation. Call it lack of courage if you will. Ahhh! Let me exhume old ghosts... Simula67 uses := for assignment, and :- for reference assignment. You would have invented nothing new, and adopted a well known tradition, if you had used :- for reference (in the Simula67 sense) assignment. Also, I am incredibly amused by the idea that actually :- *is* the leading part of :-)... NOTE: I find it worrying that the author of Eiffel, a person that I greatly esteem, is not extremely familiar with Simula67 and Lisp. Now some embarassing questions: Has he ever read the Simula67 Common Base standard? Simula BEGIN? What is Hash Consing and how does it relate to this discussion? What is rplac[ad] and how does it relate to this discussion? NOTE on NOTE: many will have noted (:->) that one of my pet peeves is moaning about the lack of historical perspective by most computer scientists (especially, let me say, American (ised :->) ones wrt much European research). I apologise in advance for the irritation this mania causes... -- Piercarlo "Peter" Grandi | ARPA: pcg%cs.aber.ac.uk@nsfnet-relay.ac.uk Dept of CS, UCW Aberystwyth | UUCP: ...!mcvax!ukc!aber-cs!pcg Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg@cs.aber.ac.uk
bertrand@eiffel.UUCP (Bertrand Meyer) (07/10/89)
From article <PCG.89Jul8222705@thor.cs.aber.ac.uk>, by pcg@thor.cs.aber.ac.uk: > Pascal and Ada have a concept of pointer, > and indeed := is used by them to do *copy* of pointer objects. This > is VERY different from Eiffel. Unless there is something I don't understand I am afraid Mr. Grandi is mistaken. Both in Pascal and in Ada := is used for pointer assignment. For Pascal, see chapter 10 of Pascal User Manual by Kathleen Jensen and Niklaus Wirth, Springer-Verlag, 1974 (pages 62-66 in the second edition); also the ``Report'' part of the same book, section 7.3. For Ada, the relevant section of the Reference Manual (3.8) is not the most luminous piece of technical literature ever written, but there is no doubt that the semantics is indeed that of pointer assignment. (See for example ``Ada for Experienced Programmers'' by A. Nico Habermann and Dewayne E. Perry, Addison-Wesley, 1983, page 197.) Interestingly enough, Pascal and Ada both also use := to prescribe value assignment for referenced records. I believe the correct notations are p^ := q^ in Pascal and p.all := q.all in Ada. As explained in my article on ``Eiffel types'', there are cases in which one *explicitly wants* to have the same symbol express different semantics for reference types and expanded types. (The latter is Eiffel 2.2 terminology for types whose elements are objects rather than references to objects; expanded types include the basic types INTEGER, REAL, DOUBLE etc.) Thanks to expanded types and the associated assignment and argument passing conventions, Eiffel 2.2 allows programmers to choose exactly what they need in a given case: uniform copy semantics, or variable semantics. This is particularly important for generic classes. > I find it worrying that the author of Eiffel [...] > is not extremely familiar with Simula67 and Lisp. > Now some embar[r]assing questions: Has he ever read the Simula67 > Common Base standard? Simula BEGIN? What is Hash Consing and how > does it relate to this discussion? What is rplac[ad] and how does > it relate to this discussion? > This is an interesting idea: Usenet as an ongoing certification program, or people's tribunal (``You don't even know the basics!'', shouts the Red Guard to the Mandarin). It is tempting to reply, as Mitterrand to Giscard d'Estaing during the 1981 presidential debate, ``I am not your student, and you are not my professor'', but let me not be stuffy and indeed answer. The author of Eiffel did write more than a few Lisp and Simula programs, thank you. One of my first programming courses was a Lisp course taught by Prof. John McCarthy; I remember him as reasonably competent on the subject. On Simula, please see ``Quelques concepts importants des langages de programmation modernes, et leur expression en Simula 67'', by the undersigned, GROPLAN 9, AFCET, 1979. (English version presented at the Tenth Conference of the Association of Simula Users, Oslo, in, I believe, 1980 or 1981.) As to rplaca and rplacd, the definition I am tempted to give is ``If you like the idea of functional programming, the main arguments for using Miranda rather than Lisp''. -- Bertrand Meyer bertrand@eiffel.com