Notice what is said in the Robert C. Martin article I liked to
and used as support. He states that the abstraction/higher
level code (my use) should be in the application code (other
use).
Which only makes sense: the application is the highest level, in
the sense I'm using the words.
In other words the uses are not actually different.
I never said that these STL routines were the highest level of
abstraction. They are specific algorithms and data container
types. Higher levels might make use of more abstraction that
allows any container to be used. These very well might make
use of templates.
Kanze is trying to claim that template code belongs only in
the "lower" levels and not in "application code" and I'm
trying to show that this just isn't true.
I'm not "claiming"; I'm constating. Templates, as implemented
by most compilers today, don't work well at the application
level. It's not a big problem, yet, because typically, most
polymorphism at the application level needs to be dynamic. The
need for templates is less.
Today, at least. Like most people, I'm intreged by the
possibilities of TMP. For the moment, however, it's not
generally used at the application level, and we can't really
experiment too much with it to determine whether it is relevant
or not at this level, because of the way most compilers
implement templates.
He's used as his backing to this argument that the STL is low
level code. I've tried to show that this also is not true,
and I think I've done a fairly good job of that.
You've not shown anything. The STL is extremely low level, in
this sense, since it is (formally) part of the compiler; it
depends on nothing else.
Perhaps it is a problem of definition. In this case, I'm not
arguing about the level of abstraction (although the STL is
pretty low level in this respect, as well); I'm arguing about
dependencies.
Actually, even dependencies, and low level vs. high, probably
aren't the issue. Stability is. Templates don't work in code
that isn't stable, because of the dependencies they introduce.
Application level code is normally the least stable; if the
application requirements change, you have to change it, and if
the application requirements don't change, you don't have to
change anything. The STL, as part of the compiler, is the most
stable---you don't ever change anything in the STL yourself, and
of course, if you change compilers---something you don't want to
do very often---you do a complete rebuild anyway.
Anyway, the fact remains that in well run shops developing large
applications, the use of templates is strictly limited to the
most stable, lower levels, and this is really where they are
most essential.
STL objects and algorithms are relatively high level pieces of
code. They perform a set of abstract functionality that is
not specific to any particular data type until instantiated
(and can even work with polymorphic types with some wrapping).
But they still expose far too many "details". When is an
iterator valid? It depends on the type of container.
Unlike say operations like strcmp or memset, which work at a
low level on a particular data type (raised only in the use of
vague pointers), the templated nature of STL operations allow
them to work on any data type.
Dynamic polymorphism can be more abstract but static
polymorphism can also be quite abstract and can solve many
problems at the *highest* levels of your *application code*.
Certainly. But that's not really the issue here. The issue is
that at the highest levels of application code---code which is
changing constantly---templates, as currently
implemented by most compilers---don't work. And at present,
it's not really an issue, because they're not that necessary.
Although TMP shows some promess of being applicable for certain
things at that level, the technology isn't stable enough or
mature enough that you'd want to use it yet.
It makes no sense to say that they should only be used in low
level development since they frankly don't actually fit there
too well. Low level is where you have specifics, places where
a particular non-abstraction is manipulated. This is not what
templates are. Chances are that your code will be more
dynamically than statically polymorphic but this does not mean
that static polymorphisms are for low level code nor that it
isn't perfectly appropriate in application code.
I would even go as far as saying that generic programming is a
higher level, more abstract AND higher in structure, than oop.
Which, of course, is silly, unless you redefine higher level to
mean something it has never meant.
In terms of *flexibility* (which I think is what you're really
talking about), there is the old argument of static vs. dynamic
typechecking. Languages like Smalltalk or lisp, which have
fully dynamic type checking, are more flexible than C++ or Java,
which do static type checking. This flexibility comes at a cost
in robustness, however; while people have done it, I'd be very
sceptical of writing a concrete application (as opposed to
prototyping) using a dynamically typed language. In the case of
C++ templates, we have a case of dynamically typed polymorphism,
but since the polymorphism is resolved at compile time, we do
not loose the robustness of compile time type checking. (On the
other hand, we do loose the flexibility of having it resolved at
run time. It's a different compromise.)