craig@gpu.utcs.utoronto.ca (Craig Hubley) (02/16/91)
Since there was a recent post about this very issue in comp.std.c++, since it's a question about the desirability of changing something in the language, and a stream was already going on this subject here, I have cross-posted this and directed followups to comp.std.c++, which I believe is the appropriate forum for such discussions. In article <DSOUZA.91Feb14151948@optima.cad.mcc.com> dsouza@optima.cad.mcc.com (Desmond Dsouza) writes: > >In article <600@taumet.com> steve@taumet.com (Stephen Clamage) writes: > > craig@gpu.utcs.utoronto.ca (Craig Hubley) writes: > > |Now that C++ has three polymorphism mechanisms > | - overloading (compile-time) > | - templates (link-time) > | - virtual functions (run-time) > > |Is anyone thinking about how to reconcile them ? As it stands now, I can > |use overloading to add extra arguments to functions, etc., but I can't do > |it in my derived classes because virtuals can't be overloaded, etc. I stated this badly. They can't be overloaded in the way I want, that is, to allow pointers to derived classes as return values in place of pointers to bases, and pointers to base classes as arguments in place of pointers to derived, and have such an overload override the original function. That is, I want the compiler to override the base class's function wherever a derived function is defined that - accepts a parameter list convertible to one the base would accept - returns a value of a type convertible to one returned by base my definition of "convertible" is quite restrictive here: pointers to derived classes, which are legal substitutes for pointers to bases. I am interested in discussing expanding this definition to include other builtin conversions, but I do not think it should extend to user-defined ones. For one thing, the overriding rules should NOT depend on user-defined code, which can change and cause unexpected chaos. But the builtin conversions will not change in this fashion, and are largely there to ease the pains of dealing with the C data types, and to manage inheritance. Other OO languages permit such type-compatible overloading, and in some languages (e.g. Trellis) it is enforced. That is, you can only define changes that will leave a derived type a legal substitute for a base type in all circumstances (i.e. type-safe). > Overloading need have no relation to polymorphism. > Templates and polymorphism are orthogonal concepts. > Virtual function may be overloaded. > >The rules for overloading resolution with class derivation is >remarkably similar to the virtual function mechanism (in fact, it >resembles 'multi-methods' with dispatch based on the derivation >closeness of *all* arguments, instead of just the 'this' pointer), >except the work is done at compile-time. I suppose I am suggesting they ought to be one mechanism, not two. Overloaded functions should also be permitted to return "more specialized" types and accept "more general" arguments. >Templates are the C++ implementation of what Cardelli called >'parametric polymorphism'. You could say templates and class >derivation/virtuals are orthogonal, except that template-instantiated >classes could have meaningful class-derivation relationships between >them. e.g. read-only-list<cars> Vs read-only-list<sports-cars> Thanks for the reference. To invoke Trellis again, its type-generators (equivalent to templates) can be declared "not_flat" which simply means that the generated types (e.g. collections) have the same inheritance relationship as the type used to generate them. >Virtual functions may NOT be overloaded in the manner Craig seems to want. Not at present, although I think a strong case can be made for the change. >A derived class,D, with a virtual functions D::f whose arguments >differ from those of its base class,B, HIDES the base class function, >and does not override B::f. Doing otherwise breaks type-safety. See This is a rather narrow notion of type-safety. I would argue that the general theory does not apply here. C++ recognizes distinct types but also blurs the distinction between some types (e.g. pointers to base vs. derived, numerical types) with its unique builtin type conversion. This causes some things of "different" type to be guaranteed to be treated as if they were the same, so long as not more than one user-defined conversion is invoked, and I am suggesting we leave them out of this completely. In this case, the argument list may well be convertible to one that B::f will accept, and with only builtin conversions being invoked. There is no change to any user program that will cause this conversion to be invalid, thus this argument list is always a valid substitute for that of B::f. > craig@gpu.utcs.utoronto.ca (Craig Hubley) writes: > > >To propose one small change, if virtuals could be overloaded in type- > >compatible ways (i.e. redefining acceptable rguments as pointers to base > >classes in place of pointers to base classes, returning pointers to derived > >classes in place of pointers to base classes, and permitting extended > >argument lists where defaults have been provided) this would add no more > >work to the compiler than a simple decision to exhaust matching on virtual > >functions before trying for an exact match at a different level, and no > >overhead at all to user programs that did not use these features. > >In effect it is no more than removing some arbitrary constraints on typing > ^^^^^^^^^ > >that are inconsistent with the rules in the rest of C++, which is exactly > >the kind of change we have been seeing between versions of C++. > >'Arbitrary' ? Thats kinda strong! Sometimes inconvenient, yes. I will stick to my gadfly term. Every other language that pretends to be OO at least permits, usually encourages and sometimes enforces what I propose. It arises from sound principles, and C++ is arbitrary in flouting them without a clear reason that is stated in practical terms, not with abstract terms like "type safety" which I have demonstrated mean something different in C++ than in other languages. Second, C++ itself permits data values of these types to be freely substituted but somehow flinches at permitting functions that return these types from being similarly substituted (i.e. overloaded functions can't return the more specialized type). Thus it is inconsistent with itself. >1 Redefining acceptable arguments to be pointers to derived classes > (I'm assuming thats what you meant) instead of to base classes will > break strong typing. No, the opposite. You can *generalize* arguments but not *specialize* them without risking failures. The derived virtual may try to use aspects of the derived type it expects, when only the base type is there, since that was what the original base virtual expected, and that was what programmers provided. That would be equivalent to automatically casting B* to D*... which C++ doesn't do. If the base class has a virtual thus: class B { virtual B* foo(D*); } Then this is what we are talking about (comment from a previous post) class D : public B { // D* is always demotable to B*, so the function call B* foo(B*) {}; // D::foo(D*) should be equivalent to D::foo((B*)D*) // It could also be interpreted as B::foo(D*), which // might be why it's illegal, but a simple rule to // exhaust argument matching on virtuals before trying // the base functions (if they are tried at all) would // resolve this ambiguity. } And this is what we were talking about above: class E : public B { D* foo(B*) {}; // Similarly, any context that ends up calling // D::foo() where B::foo() is expected will // receive a D* value that can be used as a B*. // But C++ says that overloads and virtuals // can't change the return type at all. Why not // allow it where the objects are the same size // and C++ already has a built-in promotion ? } You are "doing the same" (D) or "doing more" (E) with "less information". And here are the consequences: // if all of the above were allowed, extending C++ consistently with the // rules mentioned above yields the following results: // main { B* b; D* d; E* e; b->foo(b); // illegal, fine, B* shouldn't automatically promote b->foo(d); // legal, exact match, return B* d->foo(b); // legal, exact match, return B* d->foo(d); // legal, D::foo((B*)d), return B*, ignore B::foo(D*) e->foo(b); // legal, exact match, return D* e->foo(d); // legal, E::foo((B*)d), return D*, ignore B:foo(D*) } Whether there are any other consequences, is up to us to determine. :) >2 Returning pointers to derived classes in place of pointers to base > classes requires a change to function call/return sequences, > particularly if the implementation follows the cfront model of > laying out multiply-inherited classes and virtual tables. It can, > however, be done without compromising type safety. Agreed. I didn't expect it would be a picnic for compiler writers. It is people using and writing code I am thinking about. There was an excellent post in comp.std.c++ showing the kind of problems that are created by NOT having this mechanism. >3 Extended argument lists in the derived class would definitely change > the function call sequence, since optional arguments are currently > completely resolved at compile time. We haven't really talked about the implications of allowing extended lists. One issue with such a change would be that calls to virtual functions using the extended arguments are incompatible with the original base function. Perhaps the compiler should reject any such call where the base (with the shorter argument list) is one of the object's potential types. In other words, it's only legal where I declare, say, a D* or pointer to a type derived from D, but not where I declare a B*. It would be nice to have a way to test the actual type, and do type-specific things in the case arm where the type is guaranteed to match, but C++ doesn't allow programmers to see the darn type tag at all. >Note that you *can* have these three together: >a. B::f(B*) >b. D::f(B*) >c. D::f(D*) > >But b) overrides a), while c) does not override a). Yes. This is fine. But my point is given: d. B* B::f(D*) e. B* D::f(D*) f. D* D::f(D*) g. D* D::f(B*) h. B* D::f(B*) e) overrides d) f) should be allowed and overrides d) (compile error if e) already exists) g) should be allowed and overrides d) (compile error if e) or f) exists) h) for completeness, should be allowed, overrides d), unless e)-g) exist) Calls to d) plus the builtin conversion would invoke f)-h) correctly. Values returned by f) and g) are converted by builtins to those acceptable by any context originally calling d). >1 --> really boils down to the > "contravariant Vs covariant" >controversy. The contravariant rule, which guarantees strong typing, >does NOT allow D::f(D*) to override B::f(B*). The covariant rule >allows it, but can fail at run-time in some circumstances. This isn't what I'm proposing, as I make clear above. I'm against runtime failure in C++, and as stated above I don't think the general principles of strong typing can be applied to C++ unless one deals explicitly with the builtin conversions. >I think some of these limitations can be avoided if the compiler is >allowed to generate 'customized' code, like the Self compiler does. >e.g. 2 versions of D::f() -- one to be called from a B* object, the >other from a D* object (or multiple entry points) and emit some >run-time type checks and type conversions in the B* version. This is a possibility, I see no reason for C++'s compiler to always default towards braindeath, and it satisifies the rule that it costs nothing if you don't ever try to use this feature. But as Bjarne said, this would "bless contravariance". >but thats a pretty major change :-) I agree. I don't see much reason for it. C++ is designed to let you do this sort of thing for yourself, to some degree, although testable type tags are certainly required to do it right. You just gotta SEE the type of the object sometimes. >Desmond D'Souza. > > Desmond D'Souza, MCC CAD Program | ARPA: dsouza@mcc.com | Phone: [512] 338-3324 > Box 200195, Austin, TX 78720 | UUCP: {uunet,harvard,gatech,pyramid}!cs.utexas.edu!milano!cadillac!dsouza -- Craig Hubley "...get rid of a man as soon as he thinks himself an expert." Craig Hubley & Associates------------------------------------Henry Ford Sr. craig@gpu.utcs.Utoronto.CA UUNET!utai!utgpu!craig craig@utorgpu.BITNET craig@gpu.utcs.toronto.EDU {allegra,bnr-vpa,decvax}!utcsri!utgpu!craig
chip@tct.uucp (Chip Salzenberg) (02/18/91)
According to craig@gpu.utcs.utoronto.ca (Craig Hubley): >I want the compiler to override the base class's function wherever >a derived function is defined that > - accepts a parameter list convertible to one the base would accept > - returns a value of a type convertible to one returned by base >my definition of "convertible" is quite restrictive here: pointers to >derived classes, which are legal substitutes for pointers to bases. In the abstract, I like this idea. On the other hand, the fact that this rule has not existed in the language to date means that currently unrelated functions, which are separated perhaps by several layers of derivation, would suddenly become alternative implementations of the same virtual function. Also, member functions that are separately legal would suddenly conflict with each other if they were both valid overrides for a virtual function in a base class. If C++ were still being designed, or were still in use only internally to AT&T, this change might have a chance. But I think it's too late. Code that has already been written depends on all definitions of a given virtual function being identical. For the ANSI committee to change this significant aspect of the language would be irresponsible. -- Chip Salzenberg at Teltronics/TCT <chip@tct.uucp>, <uunet!pdn!tct!chip> "I want to mention that my opinions whether real or not are MY opinions." -- the inevitable William "Billy" Steinmetz
craig@gpu.utcs.utoronto.ca (Craig Hubley) (02/19/91)
In article <27BFE464.3FB9@tct.uucp> chip@tct.uucp (Chip Salzenberg) writes: >According to craig@gpu.utcs.utoronto.ca (Craig Hubley): >>I want the compiler to override the base class's function wherever >>a derived function is defined that >> - accepts a parameter list convertible to one the base would accept >> - returns a value of a type convertible to one returned by base >>my definition of "convertible" is quite restrictive here: pointers to >>derived classes, which are legal substitutes for pointers to bases. > >In the abstract, I like this idea. You're not the only one. :) In fact, if you consider that almost all OO programming languages only let programmers deal with names/pointers/ references rather than "real" objects, and often treat "derived" types as exact substitutes for "base" types, they have all already *implemented* this idea. Clearly, it doesn't present any insurmountable technical problems. Which leaves the backward-compatibility problems: >On the other hand, the fact that this rule has not existed in the >language to date means that currently unrelated functions, which are >separated perhaps by several layers of derivation, would suddenly >become alternative implementations of the same virtual function. It would be quite easy for tools like the eventual Clint to find this situation and warn about it, but the fact that it would break existing code means that a more gradual approach need be adopted. Perhaps a different keyword than "virtual" for this type of override, or a qualifier to virtual (virtual++ ? only kidding, maybe virtual* although the * is overloaded enough). Or even a compiler flag, which works in ANSI C for distinguishing old style definitions which would otherwise be illegal. >Also, member functions that are separately legal would suddenly >conflict with each other if they were both valid overrides for a >virtual function in a base class. Same answer as above. It should be easy to find such situations, after all the compiler *has to* find them to build the override table. Who needs Clint ? >If C++ were still being designed, or were still in use only internally >to AT&T, this change might have a chance. But I think it's too late. Perhaps. But there are constructs in K&R C that go boom in ANSI C, too. And one hell of a lot of people used K&R C. >Code that has already been written depends on all definitions of a >given virtual function being identical. But it is not "identical" in a semantic sense anyway. Outputting "doctor" rather than "nurse" is a different operation with different effects, even if the program can't see what they are. And I don't believe that very many people are overloading virtual functions anyway at the moment. Because the rules are a mess, which was my original point. One is reminded of the story about "make" where its designer decided not to change its horrid syntax the DAY AFTER he gave it to TEN other people. I mean, there is backwards compatibility, and then there is absurdity. ANSI is supposed to represent the economic interests of the industry as a whole. Forcing thousands of programmers doing prototypes in other OOPLs to bugger everything around to fit C++'s unique and (from what I can see) less-powerful resolution of virtuals is a far larger ongoing expense to the software industry than a flag or extra keyword. After all, when the words "catch" and "template" were added as keywords it caused some code (probably not much) which used these as variable names to break. This was OK since that was easy to spot and change. This kind of problem is easy to spot and change too: a parser can flag every instance that would be different under the old and new rules. And my guess is, there won't be many. >For the ANSI committee to >change this significant aspect of the language would be irresponsible. Only if they do it without providing a clear migration path wherein it is possible to avoid code breaking. I like the alternate or modified keyword approach. Then programmers themselves could choose which of the two means of resolution they found most useful. My expectation would be that any programmer prototyping systems in another OOPL, or those that had been taught the OO paradigm, or learned another OOPL first, like myself, would prefer the more-liberal overriding paradigm. >Chip Salzenberg at Teltronics/TCT <chip@tct.uucp>, <uunet!pdn!tct!chip> -- Craig Hubley "...get rid of a man as soon as he thinks himself an expert." Craig Hubley & Associates------------------------------------Henry Ford Sr. craig@gpu.utcs.Utoronto.CA UUNET!utai!utgpu!craig craig@utorgpu.BITNET craig@gpu.utcs.toronto.EDU {allegra,bnr-vpa,decvax}!utcsri!utgpu!craig
cok@islsun.Kodak.COM (David Cok) (02/19/91)
In article <27BFE464.3FB9@tct.uucp> chip@tct.uucp (Chip Salzenberg) writes: >According to craig@gpu.utcs.utoronto.ca (Craig Hubley): >>I want the compiler to override the base class's function wherever >>a derived function is defined that >> - accepts a parameter list convertible to one the base would accept >> - returns a value of a type convertible to one returned by base >>my definition of "convertible" is quite restrictive here: pointers to >>derived classes, which are legal substitutes for pointers to bases. > >In the abstract, I like this idea. > >On the other hand, the fact that this rule has not existed in the >language to date means that currently unrelated functions, which are >separated perhaps by several layers of derivation, would suddenly >become alternative implementations of the same virtual function. > >Also, member functions that are separately legal would suddenly >conflict with each other if they were both valid overrides for a >virtual function in a base class. > >If C++ were still being designed, or were still in use only internally >to AT&T, this change might have a chance. But I think it's too late. >Code that has already been written depends on all definitions of a >given virtual function being identical. For the ANSI committee to >change this significant aspect of the language would be irresponsible. My original post which started part of this thread asked only for the second of Craig's requests (including references as well as pointers) -- that Given base class B and derived class D and virtual functions virtual B* B::f(); virtual B& B::g(); that the derived class be able to supply its versions of these virtual functions as D* D::f(); // these currently illegal D& d::g(); instead of B* D::f(); // these currently legal B& D::g(); Either (but not both at once) returning D* or returning B* would be legal. Since returning D* is now illegal, no code would break or have its semantics changed. I realize that this proposal does not address all the concerns of other posters (e.g. Craig Hubley) related to conversions on function parameters. However, in my (couple of years) of C++ use being able to do what I propose for return types would have reduced the number of helper functions and lines of code significantly (10s of percent), whereas the restrictions on function argument types have rarely been a problem for me. I'd be interested in real (I can invent by own) examples where allowing conversions on function arguments caused a significant simplification. David R. Cok Eastman Kodak Company cok@Kodak.COM
chip@tct.uucp (Chip Salzenberg) (02/21/91)
According to craig@gpu.utcs.utoronto.ca (Craig Hubley): >I want the compiler to override the base class's function wherever >a derived function is defined that > - accepts a parameter list convertible to one the base would accept > - returns a value of a type convertible to one returned by base >my definition of "convertible" is quite restrictive here: pointers to >derived classes, which are legal substitutes for pointers to bases. > >Perhaps a different keyword than "virtual" for this type of override, or >a qualifier to virtual (virtual++ ? only kidding, maybe virtual* although >the * is overloaded enough). I didn't even think of the "virtual*" kind of language addition. In that context, I could go for it. >But there are constructs in K&R C that go boom in ANSI C, too. Granted. Try, catch and throw will make my programs go boom until I change my variable names. >>Code that has already been written depends on all definitions of a >>given virtual function being identical. > >But it is not "identical" in a semantic sense anyway. What the captain meant to say was, "... being identically typed." >Forcing thousands of programmers doing prototypes in other OOPLs to >bugger everything around to fit C++'s unique and (from what I can see) >less-powerful resolution of virtuals is a far larger ongoing expense to >the software industry than a flag or extra keyword. This statement belies an assumption that all OOPLs are, or should be, semantically equivalent. It ain't so, nor should it be: an approach (OOP) does not a language make. Smalltalk is a great environment, but it's lousy for prototyping C++ programs. -- Chip Salzenberg at Teltronics/TCT <chip@tct.uucp>, <uunet!pdn!tct!chip> "It's not a security hole, it's a SECURITY ABYSS." -- Christoph Splittgerber (with reference to the upage bug in Interactive UNIX and Everex ESIX)
craig@gpu.utcs.utoronto.ca (Craig Hubley) (02/22/91)
In article <1991Feb19.120934.22963@kodak.kodak.com> cok@islsun.Kodak.COM (David Cok) writes: >In article <27BFE464.3FB9@tct.uucp> chip@tct.uucp (Chip Salzenberg) writes: >>According to craig@gpu.utcs.utoronto.ca (Craig Hubley): >>>I want the compiler to override the base class's function wherever >>>a derived function is defined that >>> - accepts a parameter list convertible to one the base would accept >>> - returns a value of a type convertible to one returned by base >>>my definition of "convertible" is quite restrictive here: pointers to >>>derived classes, which are legal substitutes for pointers to bases. > >My original post which started part of this thread asked only for the >second of Craig's requests (including references as well as pointers) -- that > > ... nice description omitted... > >Either (but not both at once) returning D* or returning B* would be legal. >Since returning D* is now illegal, no code would break or have its >semantics changed. > >I realize that this proposal does not address all the concerns >of other posters (e.g. Craig Hubley) related to conversions on function >parameters. However, in my (couple of years) of C++ use being able to do So far as I know I am the only one on the net at present proposing that these conversion rules be extended explicitly to function parameters. The language already supports an implicit form of this, of course, by allowing conversions to be invoked when calling a function. I am arguing for it to be made explicit. My concern is that several levels down in the type matrix these restrictions on optional arguments or on declaring the type of the argument will become unacceptable, and I (or someone else) will have to create a new function with a new name. Thus a set of capabilities that could have been one polymorphic function becomes two, and the complexity of knowing which to call ends up on the programmer again. This restricts reusability too, since code that deals with the base types can't handle the derived types lower down the hierarchy since the function name has changed. >what I propose for return types would have reduced the number of helper >functions and lines of code significantly (10s of percent), whereas the I would agree with this assessment. >restrictions on function argument types have rarely been a problem for me. Probably because of the already-powerful conversion system. I am only proposing that this be explicitly recognized when compiling overloaded or virtual functions. >conversions on function arguments caused a significant simplification. C++ already supports such conversion, and you can see good examples of the value of it (e.g. int to float) anywhere. However, it doesn't let the programmer declare or enforce any constraints. If I was not allowed to write a function to divide even ints and produce an int, then I would always be invoking the float version at significant additional overhead. It would also be confusing if int/int produced a float, which is the issue we are addressing talking about return types. Being able to tailor based on the arguments can improve efficiency, but if C++ converts them with a general conversion function (e.g. a constructor) so that a generalized function can deal with them, this gain is lost. It is more a question of overhead than simplification in this case. -- Craig Hubley "...get rid of a man as soon as he thinks himself an expert." Craig Hubley & Associates------------------------------------Henry Ford Sr. craig@gpu.utcs.Utoronto.CA UUNET!utai!utgpu!craig craig@utorgpu.BITNET craig@gpu.utcs.toronto.EDU {allegra,bnr-vpa,decvax}!utcsri!utgpu!craig
craig@gpu.utcs.utoronto.ca (Craig Hubley) (02/22/91)
In article <27C30630.523F@tct.uucp> chip@tct.uucp (Chip Salzenberg) writes: >>Forcing thousands of programmers doing prototypes in other OOPLs to >>bugger everything around to fit C++'s unique and (from what I can see) >>less-powerful resolution of virtuals is a far larger ongoing expense to >>the software industry than a flag or extra keyword. > >This statement belies an assumption that all OOPLs are, or should be, >semantically equivalent. It ain't so, nor should it be: an approach Not equivalent, just consistent where other languages with longer experience have proven the way to go. The training and conversion expense to the industry of C++'s "unique" approach requires explicit justification, and I don't see it anywhere. >(OOP) does not a language make. Smalltalk is a great environment, but >it's lousy for prototyping C++ programs. With multiple inheritance and better interoperation with other languages, it might be better for prototyping a C++ type hierarchy, though. Except that you would be managing all the strong typing yourself. I am on the fence about Smalltalk as a prototyping tool. In prototyping I like terrifyingly powerful tools like LISP/LOOPS (haven't done enough with CLOS) that let me not only shoot myself in the foot, but microwave myself. -- Craig Hubley "...get rid of a man as soon as he thinks himself an expert." Craig Hubley & Associates------------------------------------Henry Ford Sr. craig@gpu.utcs.Utoronto.CA UUNET!utai!utgpu!craig craig@utorgpu.BITNET craig@gpu.utcs.toronto.EDU {allegra,bnr-vpa,decvax}!utcsri!utgpu!craig
dsouza@optima.cad.mcc.com (Desmond Dsouza) (02/26/91)
craig@gpu.utcs.utoronto.ca (Craig Hubley) writes: > >1 Redefining acceptable arguments to be pointers to derived classes > > (I'm assuming thats what you meant) instead of to base classes will > > break strong typing. > > No, the opposite. You can *generalize* arguments but not *specialize* > them without risking failures. The derived virtual may try to use aspects > of the derived type it expects, when only the base type is there, since > that was what the original base virtual expected, and that was what > programmers provided. That would be equivalent to automatically casting > B* to D*... which C++ doesn't do. > OK, what you want would be type safe (arguments are contravariant). There was recently a long discussion on this in comp.object. Bertrand Meyer claimed that few cases, if any, need a derived class to have *more* general arguments than its base class, and used this to support co-variance instead of contravariance. If you have convincing examples which do need contravariance, could you post them? Note also that implementing this could also mean change to function call/return sequences, specially with the cfront implementation of multiple-inheritance, where converting Derived to Base pointers involves run-time checks and offsets. Multiple compiler-generated versions of functions, or multiple entry points, can eliminate the overhead of this when it is not used. Returning a pointer (reference) to a derived class instead of a base class is definitely useful, though it has similar effects on implementation efficiency in call/returns. -- Desmond. -- ------------------------------------------------------------------------------- Desmond D'Souza, MCC CAD Program | ARPA: dsouza@mcc.com | Phone: [512] 338-3324 Box 200195, Austin, TX 78720 | UUCP: {uunet,harvard,gatech,pyramid}!cs.utexas.edu!milano!cadillac!dsouza
jimad@microsoft.UUCP (Jim ADCOCK) (02/27/91)
In article <1991Feb21.185106.20605@gpu.utcs.utoronto.ca> craig@gpu.utcs.utoronto.ca (Craig Hubley) writes: |Not equivalent, just consistent where other languages with longer |experience have proven the way to go. If old languages *had* proven the right way to go, people wouldn't still be deriving new languages today. C++ already is saddled with restrictions imposed by attempting to be compatible with one old language. Let's not add more!
craig@gpu.utcs.utoronto.ca (Craig Hubley) (03/03/91)
In article <70903@microsoft.UUCP> jimad@microsoft.UUCP (Jim ADCOCK) writes: >In article <1991Feb21.185106.20605@gpu.utcs.utoronto.ca> craig@gpu.utcs.utoronto.ca (Craig Hubley) writes: > >|Not equivalent, just consistent where other languages with longer >|experience have proven the way to go. > >If old languages *had* proven the right way to go, people wouldn't still >be deriving new languages today. I disagree. No one language had all the answers, nor is it possible for one language to make the "right" engineering tradeoffs for all people and all applications. We went through this in the 60s with PL/1, and in the 70s with Ada... We gotta learn from our mistakes, too... and I don't believe that type tags were originally in any of those other languages, they were added as it was realized there were situations that required them. People will be deriving new languages so long as there are new needs and new technologies to meet them. C++ is a response to a need for an efficient data abstraction language. Making it a good reusable code language ought to fit somewhere between "efficiency" and "data abstraction" on the priority scale. >C++ already is saddled with restrictions >imposed by attempting to be compatible with one old language. > >Let's not add more! If you mean "don't mimic the functionality of other languages", I agree, there are enough problems supporting C already. However, if a mechanism from Smalltalk or whatever seems to work and solve a problem in C++, why not mimic it ? The alternative is to invent it over and over in practice, training everyone how to do it, or worse, to invent it in a standards committee... -- Craig Hubley "...get rid of a man as soon as he thinks himself an expert." Craig Hubley & Associates------------------------------------Henry Ford Sr. craig@gpu.utcs.Utoronto.CA UUNET!utai!utgpu!craig craig@utorgpu.BITNET craig@gpu.utcs.toronto.EDU {allegra,bnr-vpa,decvax}!utcsri!utgpu!craig