oop - Why is the C++ STL is so heavily based on templates? (and not
on *interfaces*)
            itemprop="text">
I mean, aside from its obligating name
            (the Standard Template
            Library)...
C++ initially intended to
            present OOP concepts into C. That is: you could tell what a specific entity could and
            couldn't do (regardless of how it does it) based on its class and class hierarchy. Some
            compositions of abilities are more difficult to describe in this manner due to the
            problematics of multiple inheritance, and the fact that C++ supports the concept of
            interfaces in a somewhat clumsy way (compared to java, etc), but it's there (and could
            be improved).
And then templates came into play,
            along with the STL. The STL seemed to take the classical OOP concepts and flush them
            down the drain, using templates instead.
There
            should be a distinction between cases when templates are used to generalize types where
            the types themeselves are irrelevant for the operation of the template (containers, for
            examples). Having a vector makes perfect
            sense.
However, in many other cases (iterators
            and algorithms), templated types are supposed to follow a "concept" (Input Iterator,
            Forward Iterator, etc...) where the actual details of the concept are defined entirely
            by the implementation of the template function/class, and not by the class of the type
            used with the template, which is a somewhat anti-usage of
            OOP.
For example, you can tell the
            function:
void
            MyFunc(ForwardIterator<...>
            *I);
Update:
            As it was unclear in the original question, ForwardIterator is ok to be templated itself
            to allow any ForwardIterator type. The contrary is having ForwardIterator as a
            concept.
expects a Forward Iterator only by
            looking at its definition, where you'd need either to look at the implementation or the
            documentation for:
template
             void MyFunc(Type
            *I);
Two
            claims I can make in favor of using templates: compiled code can be made more efficient,
            by tailor-compiling the template for each used type, instead of using vtables. And the
            fact that templates can be used with native
            types.
However, I am looking for a more profound
            reason why abandoning classical OOP in favor of templating for the STL? (Assuming you
            read that far :P)
              itemprop="text"> 
The short
            answer is "because C++ has moved on". Yes, back in the late 70's, Stroustrup intended to
            create an upgraded C with OOP capabilities, but that is a long time ago. By the time the
            language was standardized in 1998, it was no longer an OOP language. It was a
            multi-paradigm language. It certainly had some support for OOP code, but it also had a
            turing-complete template language overlaid, it allowed compile-time metaprogramming, and
            people had discovered generic programming. Suddenly, OOP just didn't seem all that
            important. Not when we can write simpler, more concise and more
            efficient code by using techniques available through templates and generic
            programming.
OOP is not the holy grail. It's a
            cute idea, and it was quite an improvement over procedural languages back in the 70's
            when it was invented. But it's honestly not all it's cracked up to be. In many cases it
            is clumsy and verbose and it doesn't really promote reusable code or
            modularity.
That is why the C++ community is
            today far more interested in generic programming, and why everyone
            are finally starting to realize that functional programming is quite clever as well. OOP
            on its own just isn't a pretty
            sight.
Try drawing a dependency graph
            of a hypothetical "OOP-ified" STL. How many classes would have to know about each
            others? There would be a lot of dependencies. Would you be able to
            include just the vector header, without also getting
            iterator or even iostream pulled in?
            The STL makes this easy. A vector knows about the iterator type it defines, and that's
            all. The STL algorithms know nothing. They don't even need to
            include an iterator header, even though they all accept iterators as parameters. Which
            is more modular then? 
The STL may not follow
            the rules of OOP as Java defines it, but doesn't it achieve the
            goals of OOP? Doesn't it achieve reusability, low coupling,
            modularity and encapsulation?
And doesn't it
            achieve these goals better than an OOP-ified version
            would?
As for why the STL was adopted into the
            language, several things happened that led to the
            STL.
First, templates were added to C++. They
            were added for much the same reason that generics were added to .NET. It seemed a good
            idea to be able to write stuff like "containers of a type T" without throwing away type
            safety. Of course, the implementation they settled on was quite a lot more complex and
            powerful.
Then people discovered that
            the template mechanism they had added was even more powerful than expected. And someone
            started experimenting with using templates to write a more generic library. One inspired
            by functional programming, and one which used all the new capabilities of
            C++.
He presented it to the C++ language
            committee, who took quite a while to grow used to it because it looked so strange and
            different, but ultimately realized that it worked better than the traditional
            OOP equivalents they'd have to include otherwise. So they made a few
            adjustments to it, and adopted it into the standard
            library.
It wasn't an ideological choice, it
            wasn't a political choice of "do we want to be OOP or not", but a very pragmatic one.
            They evaluated the library, and saw that it worked very well.
            
In any case, both of the reasons you mention
            for favoring the STL are absolutely
            essential.
The C++ standard library
            has to be efficient. If it is less efficient than, say, the
            equivalent hand-rolled C code, then people would not use it. That would lower
            productivity, increase the likelihood of bugs, and overall just be a bad
            idea.
And the STL
            has to work with primitive types, because primitive types
            are all you have in C, and they're a major part of both languages. If the STL did not
            work with native arrays, it would be
            useless.
Your
            question has a strong assumption that OOP is "best". I'm curious to hear why. You ask
            why they "abandoned classical OOP". I'm wondering why they should have stuck with it.
            Which advantages would it have had?
  
No comments:
Post a Comment