In an interesting interview at http://www.stlport.org/resources/StepanovUSA.html AlexanderStepanov says: "I think that object orientedness is almost as much of a hoax as ArtificialIntelligence." See ObjectOrientationIsaHoax. ---- Stepanov is IMO needlessly hostile in his opinions towards OO. I'll try to describe the differences between generics and objects, as I've felt them, briefly in here. The more aggressive discussion follows further below... Generics cannot: * use behaviorally heterogeneous collections (for example, list of different implementations of common ABC) * more generally, forget anything about the type of a datum Objects cannot (in a language which uses StaticTyping; DynamicTyping doesn't have these restrictions): * allow routines on compound types which make no assumptions about the component types * more generally, define any polymorphic behavior without first defining an interface. Workarounds for overcoming the limitations exist in both directions. Java's downcasts are one such mechanism, and you can put objects or something providing equivalent power (functions / collections of functions) into a generic data structure. Note that there are two kinds of generics: * compile-time generics, familiar from C++, which are much akin to macros for code synthesis. * runtime generics, familiar from the SmlLanguage (ObjectiveCaml) and other FunctionalProgrammingLanguage''''''s, which are no use without HigherOrderFunction''''''s. ObjectiveCaml and HaskellLanguage both have both of the above, the former in the form of modules, the latter in the form of existential classes. ---- Later in the interview there is the following: '''Q:''' This mean a radical change of mind from both imperative and OO thinking. What are the benefits, and the drawbacks, of this paradigm compared to the "standard" OO programming of SmallTalk or, say, Java? '''A:''' My approach works, theirs does not work. Try to implement a simple thing in the object oriented way, say, max. I do not know how it can be done. Using generic programming I can write: template inline S''''''trictWeakOrdered& max(S''''''trictWeakOrdered& x, S''''''trictWeakOrdered& y) { return x < y ? y : x; } and template inline const S''''''trictWeakOrdered& max(const S''''''trictWeakOrdered& x, const S''''''trictWeakOrdered& y) { return x < y ? y : x; } ''Yeah, that's pretty easy. In Smalltalk it's much harder. Implement this method on object:'' max: anObject ^self > anObject ifTrue: [self] ifFalse: [anObject] ''Much more difficult.'' ' (you do need both & and const &). And then I define what strict weak ordered means. Try doing it in Java. You can't write a generic max() in Java that takes two arguments of some type and has a return value of that same type. Inheritance and interfaces don't help. And if they cannot implement max or swap or linear search, what chances do they have to implement really complex stuff? These are my litmus tests: if a language allows me to implement max and swap and linear search generically - then it has some potential. Can someone who knows explain what he is getting at? Is G''''''enericProgramming that much superior? ---- The name S''''''trictWeakOrdered is just a placeholder here. There doesn't need to be a class named S''''''trictWeakOrdered anywhere in the system. Including a header file containing this code in a source file allows the programmer to invoke '''max(x, y)''' anywhere therein, no matter what object types '''x''' and '''y''' are. However, the statement will fail to compile iff the statement '''x < y''' would cause a compile error. Thus, the only restriction on x and y is that '''operator<()''' exists, either as a free function taking x and y as arguments, or as a member function for the class of x taking y as argument. If x and y are native types, this is automatic. In Java, on the other hand, there are no generic functions. Some people consider this good, of course. So, the appropriate way to do this is to have x and y be members of a '''Comparable''' class (or to provide an extra '''Comparator'''), and declare a utility class: public final class Ordering { public final static Comparable max(Comparable x, Comparable y) { return (x.compareTo(y) < 0) ? y : x; } // Optional: public final static Object max(Object x, Object y, Comparator cmp) { return (cmp.compareTo(x, y) < 0) ? y : x; } // Min, median, etc. } You can then invoke Ordering.max(x,y) as appropriate. Note that Alexander Stepanov could have provided a three-argument version too. The question is, which is appropriate to your needs? -- EricJablow ''It's difficult to see what need there would be for the approach in this examples while using language with dynamic typing. It's a few years since I worked in C++, but back then we used C++ templates to fake up many things that Lisp and Smalltalk people take for granted (closures, strong collections, functoids etc). Apart from that, the advantage of '''C++ templates''', which are only one form of genericity, is a particular form of late binding. It'd be interesting to know what Stepanov would have to say about other forms of genericity.'' ''It's not clear to me quite what he's getting at with this example. Certainly, an OO (or any other kind of) language that has static typing can benefit from some explicit mechanism for genericity. Languages with dynamic typing have other mechanisms for doing the same things.'' ''As for the idea of expressing your algorithms in as abstract a fashion as possible well, probably YouArentGonnaNeedIt, plus, things like Beck's TemplateMethod do something very similar. -- KeithBraithwaite'' Java is pretty much screwed without the generics introduced in 1.5. However, for a language like SmallTalk or Lisp you are exactly right. There is no need for templates in these languages. In fact GenerativeProgramming (and unfortunate name choice that is too close to GenerativeCommunication) talks about this at length. A language with a dynamic type system does not need templates. The problem with Java is that it really rode the fence and has neither a static type system nor is it truly dynamic. As a result, it requires even more type casting than a language like C or CeePlusPlus. For this reason, it really requires templates. However, one should not confuse genericity with GenericProgramming. -- RobertDiFalco ---- Stepanov, although clearly a very smart person, apparently never recovered from that bacterial infection that sparked off the development of the StandardTemplateLibrary. -- AndrewQueisser ---- The problem I have with both the C++ and SmallTalk ways of doing things is that they don't explicitly specify the requirements for the arguments to max(). I'm very happy with Java's interfaces and would like to see a Java-like language that looks something like this: interface WeaklyComparable { boolean operator<(ThisClass other); boolean operator>(ThisClass other); }; int implements WeaklyComparable; float implements WeaklyComparable; where class T implements WeaklyComparable: boolean max(T a, T b) { if(aruby test.rb test.rb:19: Arguments must be Comparable! (ArgumentError) x=12, y=23.7, max(x,y)=23.7 x=12, y=23.7, max(x,y)=23.7 >Exit code: 1 -- PeterThoman (my first ever Wiki edit, hope this works) ---- ''Can someone who knows explain what he is getting at? Is GenericProgramming that much superior? '' I think this is a silly argument. No OO does not provide a mechanism for easily creating simple functions or programs. The intent is to manage large numbers of functions in complex programs. The value OO brings is scoping. It binds functions to their appropriate types. Note that the "generic" max() function fails when used with dissimilar data types or with types which do not have the > operator defined. -- WayneMack Right, and I think the current discussion of generic-vs-OO doesn't address the "scoping" advantages of OO languages. Those advantages are relatively well understood and the discussion has moved on. What's being discussed is whether the interface of a class should be tied to its type. In SmallTalk and other dynamically typed languages type and interface are not directly tied to each other but in C++ a regular (non-template) function can only accept arguments of a specific type or subtype. A template (generic) function can accept anything that supports the operations used within the function (max needs the < operator.) The main difference now is that interface mismatches are detected at compile time (C++) or runtime (SmallTalk, etc.) It seems to me that the generic-vs-OO discussion is carried out mostly within the C++ community because for the dynamic typing crowd there is nothing to discuss. (I'm extrapolating here, being C++ myself.) -- AndrewQueisser ---- WayneMack identifies a problem when the max() function is called with the wrong sort of object. This problem has been addressed, by using SetsOfRequirements. There is a lot of information on this in TheBoostGraphLibrary. -- JohnFletcher ---- BertrandMeyer gives an excellent summary of the debate in ObjectOrientedSoftwareConstruction; for a summary of his summary see GenericsVsSubtyping ---- The expressive difference between Generics and ObjectOrientation is in: 1 How easy it is to write a program. 1 How easy it is to read a program. 1 How easy it is to debug a program. 1 How easy it is to modify a program. If you think StaticTyping is better than DynamicTyping because you always make mistakes on method parameters, then you will very easily fix that 5% of the typing mistakes. Most mistakes are not typing mistakes though, so they can't be caught by StaticTyping. * I personally think both have their points, but you are oversimplifying. For one thing, there are formal approaches in which '''all''' computation can be reduced to a matter of types, so you can't just wave your hands and say that mistakes in types are "5%" of all errors. In truth, you (and the rest of us, too) don't know the percentage in general, even if 5% happens to be true of your own code. * It is widely believed that there is excellent evidence that it is advantageous to catch as many errors as possible as early as possible, e.g. at compile time rather than run time, so even if it '''were''' only 5%, there might be a good argument. * Pure functional languages such as Haskell raise static typing to a high art, and accomplish vastly more at compile time than is traditional in languages like C++ and Java. Writing Generics doesn't seem simpler than writing ObjectOriented programs. * You seem to be talking only about C++, and you are correct that generic programming with templates in C++ is difficult and kludgy, but this is a phenomenon confined to C++ (and possibly the forthcoming Java generics); it does not reflect on GenericProgramming in '''all''' languages. Consider the following template declarations: typedef xstr::xstring< xstr::fixed_char_buf<64> > small_string; template > class fixed_char_buf; Contrary to what rookie developers may think, the above declarations are simple compared to real production code that uses templates extensively. And that's nothing compared to the compiler errors you will get and the difficulty for debugging it. And only to achieve a 5% speed increase that never materializes because you are always debugging your code. Compare with: template _bi::bind_t::type> Find(Find_SZ R0 (Find_CCH *f) (R1), R2 r2) { typedef Find_SZ R0 (Find_CCH *F) (R1); typedef typename _bi::list_av_1::type list_type; return _bi::bind_t (f, list_type(r2)); } Also keep in mind that the code above has another disadvantage: whenever you declare new variables, there is the possibility of creating a new class at compile time, just because the parameter happens to be sightly different. The code is therefore massive and it takes too long to load. -- GuillermoSchwarz. ---- CategoryCpp CategoryCppTemplates CategoryPolymorphism CategoryProgrammingLanguageComparisons