Part of the motivation for this page came from CollectionOrientedProgramming
, where someone challenged:
There is discussion about this e.g. in StronglyTypedCollection
, but I wanted to put a summary under this more obvious page title, when I noticed that the title phrase doesn't seem to appear elsewhere on the web.
Collections aren't OO -- at least, StronglyTypedCollection
's aren't; they are orthogonal to OO, and need techniques outside the realm of OO to make them strongly typed, in parameterizing/specializing what they hold, typically via GenericProgramming
General collection classes, like Array or Dictionary, are universally provided in OO languages, but such classes are not strongly typed, in the sense that e.g. if a method expects an Array of String, nothing prevents sending it an Array of Number instead.
To create StronglyTypedCollection
s is a matter of ParameterizedTypes?
, template specialization, etc, e.g. Array<String>.
Since this is a frequently misunderstood subject, here's the central point: In a pure OO language, there is no static nor dynamic type safety for the contents of a collection; if a method requires Array of String, not any other kind of Array, it must check the contents of a passed Array by hand. In e.g. GenericProgramming, this kind of type safety is supported by the language.
This obviously doesn't cripple pure OO languages like Smalltalk; one can do nicely with general collections rather than StronglyTypedCollection
s. But I think it's an interesting point, and one of the justifications for GenericProgramming
rather than pure OO programming.
And it's things like this that motivated the addition of GenericProgramming
features to Java, for instance; it adds not just further convenience, but in some cases further type safety as well. -- DougMerritt
[Costin wishes to make a statement on the record, but dislikes it when his signed comments are edited, thus I have paraphrased and removed inappropriate phrasings, and his signature; the result is halfway between ThreadMode
, and may not perfectly reflect his feelings, but I want to move away from outright fighting ThreadMode
and towards something a little closer to DocumentMode
[Paraphrase: Statically typed or dynamically typed, this is orthogonal to OO-ness of anything. At minimum this page should be renamed. At best this page is redundant; if you want to say "ParametricPolymorphism is useful
" -- and not only for collections, by the way), and that ParametricPolymorphism
is orthogonal to OO, then this piece of trivia has been already recorded on c2, without somebody needing to create the obtuse title CollectionsArentOo
- Noted. My ultimate point in creating an apparently redundant page is not immediately clear to some.
[In response to deleted/paraphrased text, the follow exchange occurred, which should also be refactored into something closer to DocumentMode
(there appear to be some substantive points to be saved, but which are too-closely-bound to negative rhetoric to separate without some further thought): ]
Costin; why do virtually all of your posts contain the phrase "handwaving"? :)
At any rate, JavaArraysBreakTypeSafety quite nicely sums up the issue of container<base> and it's relationship with container<derived>; treating them covariantly is OK in the absence of mutation; otherwise they cannot be treated covariantly and still be type-safe, at least not without a runtime check. Since Smalltalk only has containers that can hold objects and no more specific type, it avoids the problem by definition--but suffers for it IMHO. Java arrays require runtime checks to make sure that you cannot insert a Base into a Derived; it requires this precisely because it allows Derived to be used in a context where Base is expected.
At any rate, I agree with you that the presence or absence of a subtype relationship betwen container<base> and container<derived> has little to do with whether collections are or aren't "OO". After all, the contained things can have subtype relationships (stuffing a derived into a container<base> does and ought to work--if C++, assuming pointers or references, naturally--and likewise, useful subtype relations can be found among different container types; lists and vectors might be subtypes of a more abstract "sequence", which is a refinement of a generic "collection". The C++ StandardTemplateLibrary doesn't use runtime polymorphism for this; but it does take advantage of template-expansion-time DuckTyping to form a de facto container hierarchy.
- Because I limit myself to intervening when something is blatantly wrong :) I stay by my claim that in the opening of this page no real argument is made.And a real argument cannot be made anyways, because it's violently contradicted by facts. Obviously collection frameworks in languages like Java, Ada, C#, C++, support very much the OO style of programming (in the real sense of NygaardClassification ), the classes themselves being at too low a level of details to be worth dissecting if they're OO or not. One of the claim to fame of GradyBooch was that he designed a container library ("Booch Components"). In contrast the "collection" types in Haskell or ML are functional-style software design. Scheme/Lisp collections support both functional style and OO style programming.
- Oh, and there were those countless jokes about OO papers being all about the eternal stack implementation (including, among many, the papers on LiskovSubstitutionPrinciple ). Now we are suppose to find out that not only they became a matter of joke, but the authors did not have much of a clue because CollectionsArentOo, after all. Duh. At any rate, somebody puts up some non-sense, somebody else starts to link it, and voila, anything whatsoever has some kind of standing on wiki. Better go back to programming, I'm sorry for the interruption. --Costin
Doug; I'm a bit puzzled by your recent posts on the "not OO" topic. If by "not OO" you mean "orthogonal to OO", OK... but you seem to be compartmentalizing each and every programming technique, trick, and feature into this paradigm or that paradigm.
- The nature of collections in Smalltalk is pretty much the point. You must realize that C++ templates are a form of GenericProgramming, not of pure OO, but that's not reflected in your comment. Java, too, has GenericProgramming now, of course. Both languages benefited by the addition, IMHO, although I critique the details of what they did.
Many things transcend our definitions of "paradigms", many of which are artificial distinctions anyway. I'm not a MultiParadigmWeenie cause I dig knowing about lots of different programming models and care deeply about the difference; I'm a MultiParadigmWeenie precisely because I don't care. I want to write good code, and I don't give a damn whether it's OO or functional or whateverthehell else. Obviously, knowing about the dominant paradigms is useful, so I study it as much as I can; but I prefer not to worry about what technique lies where. I often feel sorry for the SmugSmalltalkWeenies who jettison perfectly good programming techniques because they aren't OO.
- You were reading too much into the fact that I collected lots of links on CategoryNotOo. That was just laziness in not deleting more of the search results on "paradigm". The list there is shorter now.
If by "not OO", you mean "opposed to OO"; that would be wrong. But I suspect you mean the first meaning; you seem to have said so above.
- I worry about it because I'm a language (and systems) designer, not just a language user, so I need to understand the cost-benefit analysis of various techniques, tricks, features, paradigms and how to categorize and inter-relate them. Should I design a pure OO language like Smalltalk, or should I add GenericProgramming features to it? CollectionsArentOo weighs in on one aspect of what would happen in the resulting language.
- If I wrote a "break-from-loop is not structured programming" page, it would be for a similar purpose. Break is very, very handy. It is interesting to know, however, that it formally violates structured programming. To a purist, that means it's bad. To a pragmatist, that means it's good -- or rather, the technical violation doesn't matter, and it's good because it's useful. The value judgement depends on one's goals, but the categorization is simply a technical matter.
- In a similar vein, people have for a long time been interested in creating OO databases, since OO is of proven value in non-DB programming, and to avoid the issues that come up with the various approaches to stuffing OO objects into relational DBs. But then smartasses like ChrisDate come along and point out various technical problems with OO databases. :-) Well, it would be nice to fix OO DBs to avoid his critiques. But one must understand the critiques first, and a first step is to at least be able to differentiate "what is OO and what is not?", to figure out what is and is not an OO DB. That's not to say that someone who is already using some given DB necessarily needs to worry about the same issues.
- Correct, I mean orthogonal-to, not opposed-to. -- Doug
Also related: ContraVsCoVariance