here is the quote (http://www.stlport.org/resources/StepanovUSA.html) from one of the original auhors of stl:
'While in the hospital, in the state of delirium, I suddenly realized that the ability to add numbers in parallel depends on the fact that addition is associative. (So, putting it simply, STL is the result of a bacterial infection.) In other words, I realized that a parallel reduction algorithm is associated with a semigroup structure type. That is the fundamental point: algorithms are defined on algebraic structures. It took me another couple of years to realize that you have to extend the notion of structure by adding complexity requirements to regular axioms. And than it took 15 years to make it work. (I am still not sure that I have been successful in getting the point across to anybody outside the small circle of my friends.) I believe that iterator theories are as central to Computer Science as theories of rings or Banach spaces are central to Mathematics. Every time I would look at an algorithm I would try to find a structure on which it is defined. So what I wanted to do was to describe algorithms generically. That's what I like to do. I can spend a month working on a well known algorithm trying to find its generic representation. So far, I have been singularly unsuccessful in explaining to people that this is an important activity. But, somehow, the result of the activity - STL - became quite successful.'
If you want to work in an environment where a lot of people are thinking like this routinely, instead of a few lone voices in a vast sea of otherwise uninterested people, the Haskell community is doing a lot of work in this area, and able to move much faster since it's so much easier in Haskell than C++ templates (which isn't really a criticism of C++ templates, a lot of their capabilities are accidental rather than intended). This is why the Haskell community talks so much about monoids and applicatives and semigroups and a variety of other interesting structures in that area (and no, I did not forget to say monad, that structure is actually uninteresting here because it is too powerful). I believe the Fortress language is also doing some work here.
Stroustrup wrote a couple of books and papers about the history of C++, which discuss how it got the way it did. Its basically by being very pragmatic, focussed on speed, with a requirement to be C source compatible as much as possible.
Unfortunately, C++ is a language that fills a niche no-other does - the ability to write genericized systems programming code. For large systems (gcc-sized) it offers a lot of advantages over C (obviously, simplicity is not one of them). I say unfortunately because nobody can argue that C++ is beautiful, but until that niche goes away, C++ will always have a place.
"Unfortunately, C++ is a language that fills a niche no-other does"
There are an awful lot of languages out there; I would be careful with statements like this. I am not sure there is any feature or combination of features in C++ that is not equally good or better in another language.
"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."
Smalltalk has had anonymous functions in the form of block objects since 1972! And they are so fundamental to the language that all control structures and iteration constructs are implemented using them! Look at the following if/else code in smalltalk:
That sends an ifTrue:ifFalse: message with two arguments, a true block and a false block (lambdas), and if the receiver, a Boolean expression that should yield either the True or False object, is true, then the first block gets evaluated and the second ignored, and if it's false, than the second is evaluated and the first ignored.
Anonymous functions are a core part of OOP, because OOP is supposed to be a streamlined subset of Lisp, preferably with specialized message-passing syntax. The idea that anonymous functions are some recent, novel addition to OOP, or that functional programming constructs are at odds with "pure" OOP, or that by peppering your C++/Java/C# code with lambdas, your "object-oriented" code has suddenly become multi-paradigm, shows just how distorted an understanding of OOP and functional programming the average programmer, and even language designer, has.
Stroustrup clearly didn't understand OOP or Smalltalk when he bolted classes on to his wretched mess of a language, and that's why C++ looks the way it does, instead of like Objective-C, a language that was a faithful, somewhat successful attempt to add Smalltalk-style OOP to C.
C++ OOP was based on Simula, rather that Smalltalk, which was OO back in the 60's, and didn't have blocks/anon functions/lambdas. (It did have coroutines though; not sure why that didn't make it to C++).
Unlike Java or (I suppose) C#, C++ has been considered multi-paradigm certainly since 1998 with templates and the STL: this is not related to the recent addition of lambdas to the standard. Very little of the popular Boost library can be considered OO, for example, as it generally discourages inheritance hierarchies, as does most modern idiomatic C++.
So, if I get this, the "party line" was that C++ is great because it's OOP -- never mind if it actually does not provide encapsulation or modularity. Or garbage collection. Or reflection. But now it is that C++ is great because it's not OOP, it's generic. It still does not provide encapsulation or modularity.
And all of this is derived from the design choice of making it not-even-compatible with C. To me, that's ideology.
That the compiler doesn't load a bunch of .o files does not mean there's no dependency graph. There is, it's just on header files, which makes things worse. You just moved the "modularity" from the linker/loader stage to the compilation stage. Which is the opposite of modularity. You can't modify a template with LD_PRELOAD. You can't have pluggable templates. If you modify a template, you have to recompile everything that uses it.
The STL never had to be efficient. It just had to be convenient. Anyway, you won't get efficiency from generic code, because real efficiency requires knowing what's the problem you're trying to solve.
I think Go got generics much better. Pass an interface{LessOrEqual} to a Sort and you're golden.
I disagree, the STL being efficient was essential for the success of C++ since the standard from 1998.
In fact, those parts of STL that can be improved significantly are available from other libraries and are widely used in the industry (like some parts of Boost, some hash tables, etc).
Nowadays C++ is mostly used in environments where efficiency is crucial, and this have been the case for many years already. If you take this away, C++ is wildly inferior to several languages.
C++ in practice has evolved a lot. With modern C++ programming style and techniques, it's actually usable and very practical. If you see code from the 90's though... it's a complete mess. All in all I think it's worth knowing inside out, like C (but they are very different languages and trying to use C++ in a C-ish way will only lead to a 90's style mess).
I think there is a different kind of modularity which you are talking about. That a solution that brings different components together requires to know about the other components is obvious. It is about how the components can be designed as free standing modules without any direct dependencies. Of course, a better module system in C++ would be great and things are moving into this direction (clang already has a preliminary implementation of the modules spec).
It is not like the addition of templates broke C compatibility. This happened long before templates were talked about. Still, C code mostly (Yes, with tricky corners.) compiles with a C++ compiler which is great and is exactly what I would expect from a sub-set of a language. Funnily, first you complain about missing modularity due to headers and then you advocate being compatible with C, whereas exactly that feature is necessary for C compatibility.
As to the efficiency: You can actually know which problem you are trying to solve in generic programming by inspecting the properties of types and optimize according to those properties. See for example the different optimizations in standard libraries when it comes to optimizing copies to memcpy calls when called with appropriate types. There is certainly a lot of generic code that is quite efficient (see std::function which compares to native function calls or hand-written virtual function call operators, very fast vector implementations (llvm, facebook), std::thread). There is, of course, bad generic code as there is bad code in every paradigm.
Bjarne Stroustrup was never a huge OOP evangelist. He spend all of 1½ page in the first edition of "The C++ Programming Language" explaining why this technique would be useful in specific situations, back when it was not widely known.
Alexander Stepanov who designed STL is very critical of OOP. Stroustrup likes quoting him, mostly to annoy the evangelists.
The C++ "party line" on the Usenet groups back when the OOP craze was at its top and C++ was a hot new upcoming language reflected Stroustrup's view. OOP was a useful technique is certain situations.
"I think Go got generics much better. Pass an interface{LessOrEqual} to a Sort and you're golden."
That's not generics but interfaces. C++ has them too... Kind of, in C++ they are called abstract classes; eventhough you need to inherit them explicitely.
This is why you need to do type assertions when using container/heap, container/list... And this is why math.Min of two integers doesn't work without any extra work. :-)
Go is pretty cool, I like it a lot. But there are fields in which interfaces are way less powerful than generics.
"C++ is the OOP" is, unfortunately, a very popular stance, especially among people who put "C/C++/C#" on their resumes.
This has nothing to do with the "party line" whatever it might be, the C++ is as much "the OOP" as Scheme i.e. you can use its type system to implement some kind of OOP.
Garbage collection is not something to be proud of. I don't know where you got the idea that C++ as any thing but C with extensions. If you don't have to recompile after changing a template then what is the template even doing? Go is no replacement for C/++
Actually, Bruce Eckel goes over this in "Thinking in C++". Stroustrup chose not to use an object-based hierarchy, where everything inherits from one base class (like in Java and Smalltalk). This presents a problem when making generic containers (that is, a container that can hold any type of object). To solve this, generics (in the form of templates) were added to C++.
[+] [-] signa11|13 years ago|reply
[+] [-] jerf|13 years ago|reply
A sample of the interesting sort of algorithm work that you can do when you think this way: http://apfelmus.nfshost.com/articles/monoid-fingertree.html
Edit: See also the Typeclassopedia: http://www.haskell.org/haskellwiki/Typeclassopedia And if you're really interested and want to take it hardcore, Edward Kmett's video on his lens library walks through how you can derive it with this sort of logic: http://youtu.be/cefnmjtAolY?hd=1
[+] [-] pbiggar|13 years ago|reply
Very worthwhile: http://www.stroustrup.com/dne.html and http://lambda-the-ultimate.org/node/2283
Unfortunately, C++ is a language that fills a niche no-other does - the ability to write genericized systems programming code. For large systems (gcc-sized) it offers a lot of advantages over C (obviously, simplicity is not one of them). I say unfortunately because nobody can argue that C++ is beautiful, but until that niche goes away, C++ will always have a place.
[+] [-] twoodfin|13 years ago|reply
I hope he'll update it. The debates over concepts deserve a chapter at least.
[+] [-] Negitivefrags|13 years ago|reply
Those of us who like C++ see it as the language it wants to be, not the language that it is dragged in to being by it's C heritage.
[+] [-] betterunix|13 years ago|reply
There are an awful lot of languages out there; I would be careful with statements like this. I am not sure there is any feature or combination of features in C++ that is not equally good or better in another language.
[+] [-] schemer4|13 years ago|reply
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."
Smalltalk has had anonymous functions in the form of block objects since 1972! And they are so fundamental to the language that all control structures and iteration constructs are implemented using them! Look at the following if/else code in smalltalk:
(...boolean expression...) ifTrue: [...true block...] ifFalse: [...false block...]
That sends an ifTrue:ifFalse: message with two arguments, a true block and a false block (lambdas), and if the receiver, a Boolean expression that should yield either the True or False object, is true, then the first block gets evaluated and the second ignored, and if it's false, than the second is evaluated and the first ignored.
Anonymous functions are a core part of OOP, because OOP is supposed to be a streamlined subset of Lisp, preferably with specialized message-passing syntax. The idea that anonymous functions are some recent, novel addition to OOP, or that functional programming constructs are at odds with "pure" OOP, or that by peppering your C++/Java/C# code with lambdas, your "object-oriented" code has suddenly become multi-paradigm, shows just how distorted an understanding of OOP and functional programming the average programmer, and even language designer, has.
Stroustrup clearly didn't understand OOP or Smalltalk when he bolted classes on to his wretched mess of a language, and that's why C++ looks the way it does, instead of like Objective-C, a language that was a faithful, somewhat successful attempt to add Smalltalk-style OOP to C.
[+] [-] sbmassey|13 years ago|reply
Unlike Java or (I suppose) C#, C++ has been considered multi-paradigm certainly since 1998 with templates and the STL: this is not related to the recent addition of lambdas to the standard. Very little of the popular Boost library can be considered OO, for example, as it generally discourages inheritance hierarchies, as does most modern idiomatic C++.
[+] [-] protomyth|13 years ago|reply
[+] [-] lolcraft|13 years ago|reply
And all of this is derived from the design choice of making it not-even-compatible with C. To me, that's ideology.
That the compiler doesn't load a bunch of .o files does not mean there's no dependency graph. There is, it's just on header files, which makes things worse. You just moved the "modularity" from the linker/loader stage to the compilation stage. Which is the opposite of modularity. You can't modify a template with LD_PRELOAD. You can't have pluggable templates. If you modify a template, you have to recompile everything that uses it.
The STL never had to be efficient. It just had to be convenient. Anyway, you won't get efficiency from generic code, because real efficiency requires knowing what's the problem you're trying to solve.
I think Go got generics much better. Pass an interface{LessOrEqual} to a Sort and you're golden.
[+] [-] muyuu|13 years ago|reply
In fact, those parts of STL that can be improved significantly are available from other libraries and are widely used in the industry (like some parts of Boost, some hash tables, etc).
Nowadays C++ is mostly used in environments where efficiency is crucial, and this have been the case for many years already. If you take this away, C++ is wildly inferior to several languages.
C++ in practice has evolved a lot. With modern C++ programming style and techniques, it's actually usable and very practical. If you see code from the 90's though... it's a complete mess. All in all I think it's worth knowing inside out, like C (but they are very different languages and trying to use C++ in a C-ish way will only lead to a 90's style mess).
[+] [-] pmr_|13 years ago|reply
It is not like the addition of templates broke C compatibility. This happened long before templates were talked about. Still, C code mostly (Yes, with tricky corners.) compiles with a C++ compiler which is great and is exactly what I would expect from a sub-set of a language. Funnily, first you complain about missing modularity due to headers and then you advocate being compatible with C, whereas exactly that feature is necessary for C compatibility.
As to the efficiency: You can actually know which problem you are trying to solve in generic programming by inspecting the properties of types and optimize according to those properties. See for example the different optimizations in standard libraries when it comes to optimizing copies to memcpy calls when called with appropriate types. There is certainly a lot of generic code that is quite efficient (see std::function which compares to native function calls or hand-written virtual function call operators, very fast vector implementations (llvm, facebook), std::thread). There is, of course, bad generic code as there is bad code in every paradigm.
[+] [-] abrahamsen|13 years ago|reply
Alexander Stepanov who designed STL is very critical of OOP. Stroustrup likes quoting him, mostly to annoy the evangelists.
The C++ "party line" on the Usenet groups back when the OOP craze was at its top and C++ was a hot new upcoming language reflected Stroustrup's view. OOP was a useful technique is certain situations.
[+] [-] blablabla123|13 years ago|reply
That's not generics but interfaces. C++ has them too... Kind of, in C++ they are called abstract classes; eventhough you need to inherit them explicitely.
This is why you need to do type assertions when using container/heap, container/list... And this is why math.Min of two integers doesn't work without any extra work. :-)
Go is pretty cool, I like it a lot. But there are fields in which interfaces are way less powerful than generics.
[+] [-] flyinRyan|13 years ago|reply
[+] [-] Negitivefrags|13 years ago|reply
You have to recompile javascript every time you run it, does that mean that that language is incapable of being modular?
I think you are confusing two different types of modules here.
[+] [-] pandaman|13 years ago|reply
This has nothing to do with the "party line" whatever it might be, the C++ is as much "the OOP" as Scheme i.e. you can use its type system to implement some kind of OOP.
[+] [-] IheartApplesDix|13 years ago|reply
[+] [-] npsimons|13 years ago|reply
[+] [-] pootch|13 years ago|reply
[deleted]