
Why is the C++ STL so heavily based on templates? - hamidr
http://stackoverflow.com/questions/1039853/why-is-the-c-stl-is-so-heavily-based-on-templates-and-not-on-interfaces
======
signa11
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.'

~~~
jerf
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.

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>

~~~
klodolph
> monad, that structure is actually uninteresting here because it is too
> powerful

I am worried these days that people are avoiding talking about monads not
because they are not useful, but because places like HN were saturated with
talk about monads a few years back. I remember seeing several blog posts
explaining monads as some kind of revelation: like they were overloaded
semicolons, or monads were burritos, etc. So let's not try to let the
popularity of monads interfere with our respect for their powerful and simple
structure.

It's kind of like saying that sets are uninteresting in mathematics because
they are too general. The Haskell community still does talk a lot about
monads, and they are interesting and useful. Monads are what let us describe
things like the difference between IO, ST, and STM. Monads give us
generalizations of list comprehensions and give us ways to simulate
nondeterministic execution.

In short, monads are still king; but the Haskell community is much more aware
of the diversity of useful algebraic structures than it was.

~~~
jerf
"uninteresting _here_ ", which is to say, in this context. Yes, they are still
fantastically useful, despite having a terrible PR department over the past
decade, but in terms of extracting maximal usefulness from things like "this
operator is associative" they aren't very interesting, because they are too
powerful, or, equivalently, make too few guarantees.

~~~
klodolph
I still have to disagree. Covariance turns generality into specificity, so any
argument that states "monads are uninteresting here because they are very
general" should be paired with, "except in the dual case in which they are
very interesting because they are very specific."

------
pbiggar
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.

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.

~~~
Negitivefrags
C++ is a beautiful language on the inside. People just don't like it's ugly
skin.

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.

~~~
mikevm
Gah, I'm tired of these Language Wars. Every week (day?) we see posts on the
front page on why language X is the "bestest programming language eva!".

There are now a gazillion programming languages, and new ones popping up every
once in a while -- like anal warts.

I'm tired of these fucking evangelists. Seeing these posts on the front page
is like getting daily visits from Jahova's Witnesses.

Just use whatever makes you productive and your product do whatever it's
supposed to do, and most importantly, shut the fuck up. </rant>

~~~
PommeDeTerre
There's no "war". It's pretty clear that C and C++ are the most important and
dominant programming languages around, regardless of what some people may
think and say.

Almost every truly important software system is either implemented directly in
one or both of them, or heavily depends on other software implemented in one
or both of them.

In practice, you don't get implementations of languages like Java, Ruby,
Python, Perl and Go without C and C++. Even if you're using something like
JRuby, you'll still likely end up depending on a JVM written in C and/or C++.
And all of this isn't even considering that your software, regardless of the
language it's written in, will likely be dealing with an OS written in C
and/or C++, and possibly communicating with a database or some other server
software written in C and/or C++. These days, C and C++ are nearly inescapable
when implementing real-world software.

~~~
betterunix
"In practice, you don't get implementations of languages
like...Python,...without C and C++."

Unless someone takes the time to free Python from C, by doing something like
this:

<https://en.wikipedia.org/wiki/PyPy>

Really, the reason you see _interpreters_ being written in C/C++ has less to
do with any technical quality of C or C++ and more to do with something else
you mentioned:

"your software, regardless of the language it's written in, will likely be
dealing with an OS written in C and/or C++,"

Bingo. Sometimes software needs to do low-level things, even if the software
itself is high-level, and that means the software is probably going to be
making system calls. An interpreter for Python is going to have to make some
system calls, and it is much easier to do that if the interpreter is written
in the same language as the OS's API; most OSes have C APIs, and thus writing
a Python interpreter in C makes sense.

"These days, C and C++ are nearly inescapable when implementing real-world
software."

I doubt it, considering how much real-world software is being written in Java,
C#, Ruby, Javascript, etc. Not all software needs to do things that involve
directly deal with the OS. The fact that these systems are often implemented
in C does not make C inescapable; it just means that nobody has bothered to
free themselves from C yet. There is no technical feature of C that makes it
inescapable as a language, it is just what we have to deal with until we put
in the effort needed to rid ourselves of it.

------
schemer4
_"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:

(...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
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++.

------
lolcraft
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.

~~~
muyuu
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).

~~~
greyman
Yes, and what is interesting, the need for efficiency haven't faded away,
despite the computers being more powerful every year. I am a veteran C++
coder, and I still find C++ a viable choice. You are getting native compiled
objects, which is also efficient due to C legacy, AND, what is important, you
are getting this efficiency also in the very abstract code.

This I consider one of the main powers of C++ - you can basically choose which
level of abstraction do you want; the language will not limit your choices
here.

But I agree the learning curve is quite steep, it takes years to really
benefit from the language. What I found is a good practice is to define which
paradigms/language constructs will be used in a project, and then to stick
with those.

~~~
betterunix
"you can basically choose which level of abstraction do you want; the language
will not limit your choices here."

The language absolutely limits you in terms of choosing your abstractions. You
can only redefine the operators already in the language. Adding a feature like
continuations or dependent types would require a rewrite of your compiler.
There is no notion of a metaobject protocol. At best, you can get some of the
power of these abstractions by using a brittle mess of templates and objects,
and you'll be left with code that is almost unreadable as a result.

If you want to see a language that actually allows you to choose any
abstraction, even those that were unknown when the language was developed,
look at Lisp and its macro system.

------
npsimons
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++.

