Do C++ Programmers Overuse Templates?

P

peter koch

On 4 Dec., 19:36, tonytech08 <[email protected]> wrote:
[snip]
To what degree was/is the question. Even at the assembly language
instructions, there is a least common denominator. But to choose to go
the other way?
That said, there might be someone that abuse templates

Well let me "spill the beans": I WAS suggesting that templates ARE
overused and probably by the unitiated. (The follow up question
becomes apparent: Are C++ templates over-promoted?).

I don't believe so. They are very useful in many contexts.
Which begs the question: When are templates needed? Books have been
written on templates. A small corner case that has been exploded into
undue significance?

That books have been written about templates can hardly surprise
anyone. And I disagree that templates are cornercases. Templates can
be difficult to write, but everyone can use them, and everyone should.
I cannot imagine a serious program written in C++ without the use of
templates - such as e.g. the standard template library.
Boost, and other template-centric exploits. Enamoration with
templates: good or bad or ugly?

This should be an easy one for you: just show us what problems in
boost that have been solved using templates and give us a better
implementation without using them. I believe that must be the real
criteria when judging whether the temples are used or abused.
Perhaps one criteria of "goodness of code" is how minimally templates
are used?

Why would that be a good criteria? If it really was the case, you
would be able to find loads of good basic, C and Pascal code out there
- for none of these languages have templates.

/Peter
 
J

James Kanze

On 5 Dec., 10:15, tonytech08 <[email protected]> wrote:
Templates can
be difficult to write, but everyone can use them,

And that is, IMHO, one of the keys. Difficult to write is
relative, of course, and for simple containers, they're a lot
simpler than the alternatives. But not every C++ programmer (or
even not most) needs to understand all of the details of
template meta-programming.
 
J

James Kanze

A common use (the most common?) of templates seems to be
covering up the lack of type variables in the C++ type system,
like they exist in some functional languages (for example,
Standard ML.)

And the most common use of templates even today (I'm sure,
although I really don't have any statistics to support it) is to
replace the macros in <generic.h>. The main motivation for
templates was that macros weren't sufficient. (Admittedly,
we're talking here of C pre-processor macros, which is a
particularly weak and poorly designed macro language.) The
intent behind the design of templates is that they integrate
more into C++ itself; the expansion of a template requires
knowledge of the definitions of other symbols, for examples, and
at least according to the standard, doesn't require that the
definition be present in the translation unit.

(And it would have been clearer if you'd have mentionned type
variables, rather than simply stating "restrictive C++ type
system". In my mind, a "restrictive" type system is one which
doesn't allow implicit conversions, a la Pascal. C++'s type
system isn't very restrictive in that sense.)
Algorithmic template metaprogramming is very ugly and tedious
so I don't see this as a real plus for templates.

It's useful when the other traditional solutions don't work;
when the expansion really does depend on type information only
available to the compiler. Having defined such a useful
feature, I believe that the next step is to make it usable; the
syntax is rather awkward, to put it mildly. Still, I'll use it
from time to time, simply because the alternatives (in C++) are
worse.
 
J

James Kanze

Completely silly.  Such programmers are best lost anyway.

The problem isn't the programmers. Many shops forbid Boost
because it is so difficult to install and maintain. (Or for
other reasons, but the fact that it uses a non-standard build
system makes it a real pain.)

And I don't know of any serious Open Source project which
requires Boost. Most of them are overly restrictive in the
other direction---either banning templates entirely, or
seriously restricting their use.
The boost libraries may be template ridden on the inside, but
very few of them require direct interaction from the user.

The qualities of the boost library varies from one component to
the next, but it's certain that once installed, some of them
make life a lot, lot easier.
Implementation details that clients and users need to concern
themselves about unless they're actually interested.  Many of
the things boost does are not possible without templates.
Better get used to it too.  A good portion of those "template
ridden libraries" are getting sucked into the next standard.

Which will solve the installation problem:).
 
T

thomas.mertes

C++ templates have grown to be language within a language, at least
for some users. Do most programmers overuse templates? Given that C++
template techniques, and some of them are quite intricate, can lock in
an entire codebase (that is, require a ground-up re-implementation if
wanting to use another, perhaps new, language), is extreme template
use wrought with peril in the long term view of things? Is a policy
that requires "judicious" use of templates the way to go?

I think templates (generics) are a concept which is okay, but should
be improved.

I have a special view of templates:
Templates are a concept to execute something at compile time
instead of runtime. I am talking about the template instantiation
which means that the compiler inserts template parameters and
generates function (and other) definitions.

I view the template itself as just a kind of function. A template is
a function which can have types as parameters and which is executed
at compile time instead of runtime. The execution of a template at
compile time is called template instanciation.

The question is: Why do templates definitions require a syntax which
is totally different from function definitions. Other than just
being called at compile time, the possibility to have types as
parameters and a function body which contains function definitions
(for functions which should be defined when the template is
instantiated), there is no difference.

I dont know how such template generating functions could be
introduced to C++. Therefore I refrain to write examples how
code like this would look like in C++.

Instead I can show examples how this is done in a different
language. The templates/generics introduced in Seed7 just work in
the way outlined above. The 'DEFINE_MAX' template, to create the
'max' function for different types, is defined with:

const proc: DEFINE_MAX (in type: aType) is func
begin

const func aType: max (in aType: a, in aType: b) is func
result
var aType: result is aType.value;
begin
if a > b then
result := a;
else
result := b;
end if;
end func;

end func;

The body of the 'DEFINE_MAX' function contains just a normal
definition of a 'max' function for the type 'aType'. The type
'aType' is introduced as parameter of the function 'DEFINE_MAX'.
The parameter 'aType' has the type 'type'. It is necessary to
instantiate the 'DEFINE_MAX' function (template) explicit:

DEFINE_MAX(integer);
DEFINE_MAX(char);
DEFINE_MAX(string);

Note that it is necessary that the operator '>' is defined for
all types which are used in an instantiation of 'DEFINE_MAX'.
An attempt to instantiate the 'DEFINE_MAX' function (template)
with a type, where the '>' operator is missing, results in a
compile time error.

A function (template), which is capable to define 'for' statements
for different types, is explained here:

http://seed7.sourceforge.net/examples/for_decl.htm

Even abstract data types can be defined with functions (templates).

This is done in the follwing way:
An abstract data type is defined by a function (template) which
returns a type that was generated by the function. Additionally
the function (template) contains definitions for functions which
are useable for the new type. This way container types like
'array' or 'hash' can be defined.

You may argue that the C++ templates can do this also (by using
a different notation). But Seed7 templates are much more powerful,
because the can contain any code and not just function definitions.
That way 'if' statements inside the template can decide which
functions should be defined. This allows a 'set' type which is
implemented with bitsets or hash tables, dependent on the
capabilities of the base type. E.g.: Types like 'char' and 'boolean'
can be converted to integers and therefore a bitset implementation
is possible. OTOH types like 'string' have no ordinal number and
therefore hash tables are used to implement a 'set'.

I hope that my explanation gives a modern view at templates.

Greetings Thomas Mertes

Seed7 Homepage: http://seed7.sourceforge.net
Seed7 - The extensible programming language: User defined statements
and operators, abstract data types, templates without special
syntax, OO with interfaces and multiple dispatch, statically typed,
interpreted or compiled, portable, runs under linux/unix/windows.
 
T

thomas.mertes

Judicious is always good.

Sorry for diverging, but I think the world would have been a better
place if C had templates from the start. C based on templates could
have made a more regular and powerful language.

C has two fundamental generic types: arrays and pointers.

You really hit the spot.
Templates are a much more basic construct than arrays, pointers
and structs. Therefore arrays, pointers and structs should be
introduced as templates. Sadly most programming languages which
introduced templates or generics did not use this opportunity and
introduced arrays, pointers and structs as unrelated concepts.
IMHO most people don't realize that this types could be defined as
templates.
If C had
templates we could have been spared from the complicated special
syntax that were chosen for arrays and pointers. Quite likely the
semantics would have been more regular as well.

Where C ended up with

int a [12], b [12];
memcpy (b, a, sizeof b);
int* p = a, *u = 0;
int i = *p;
int (*foo (int key)) [12];
int j = (*foo (42)) [0]

C + templates could have given us

array [int, 12] a, b;
b = a; // copy semantics
pointer [int] p = address (a (0)), u = 0;
int i = p (); // call to dereference
pointer [array [int, 12]] foo (int key);
int j = foo (42) () (0);

Well, it is not possible to change the past...

For Seed7 I did a hopefully better design decision:
Arrays, pointers, structs, hash tables, sets and other types are
defined as templates. Seed7 templates do not use a special syntax
and semantic as C++, Ada and Java templates/generics do. Instead
Seed7 templates are implemented as functions which contain
definitions of functions in their body and return a type. Yes,
your did not missunderstand: It is possible that functions return
a type. Additionally types can also be used as parameters and even
type variables are possible. The Seed7 templates (functions) are
called at compile time. When called, they define a new type, define
functions which use this type and return the type. Together, with the
possibility of Seed7 to define syntactic constructs, the result looks
very similar to conventional array (and other structured) types. The
definition

var array string: myArray is 0 times "";

defines the variable 'myArray' which is initialized with an array
value of 0 strings. The term 'array string' calls the template
function 'array' with the parameter 'string'. The head of the
'array' function is defined with:

const func type: array (in type: baseType) is func

which means that it is a function (func) which returns a 'type' has
the name 'array' and a parameter (baseType) of type 'type'. The
various functions allowed for arrays, like indexing, subranges,
assignment, for-loop (foreach loop over the elements of the array),
sorting and much more, are defined in the function 'array'. This way
many constructs that other languages define (hardcoded) in the
compiler are defined in a library instead. This could go so far
that you get a different language by using a different library. I
do currently not follow this path, but at least it should be
possible. See:

http://seed7.sourceforge.net/faq.htm#boot_a_language

Greetings Thomas Mertes

Seed7 Homepage: http://seed7.sourceforge.net
Seed7 - The extensible programming language: User defined statements
and operators, abstract data types, templates without special
syntax, OO with interfaces and multiple dispatch, statically typed,
interpreted or compiled, portable, runs under linux/unix/windows.
 
T

tonytech08

sometimes programs have to be porrted to new languages.
Though I've normally done it with pretty obscure languages
(CORAL-66 anyone?). C++ isn't going to go away in the near future.


I think you've already answerdd your question. *You* consider
C++ templates a fad and think they are over-used.



what?

There is a subset of instructions that are similar between certain
processors (not RISC to CISC surely, but between, say, CISC processors
from different manufactures: someone's X86 CPU and some else's "Y"
CPU).

Given that, C++ has a lot of C++-only constructs that don't/won't map
onto another language, especially if a developer uses the kind of
things that are kind-of side effects of the major mechanisms.
the other way?

Yes, the other way: C++ moves away from "all languages are just about
the same, only the syntax is a little different" (a "for" loop in one
language is like a "for" loop in another, for example).
ah! you see I was right

Kind of: I don't really think that C++ templates are a fad, just that
there is too much emphasis on them and that they are over-used and mis-
used.
seems a rather narrow definition.

It was only meant as ONE criteria of "goodness", not THE criteria.

(Sorry fo long time before responding posterS, I have been "under the
weather").
 
T

tonytech08

what does "dead" mean?

That "the code stops here", in that it is highly C++-specific without
any hope for transformation to another language (save for probably D).
I usually try to write code that is
flexible and portable.

That's good. I seem to be on some kind of quest to another language
(as of yet not invented) and so AVOID the things in C++ that I think
are "experimental" ("experimental" as in "the grand scheme of things"
or "LONG term").
How do C++ templates fly in the face of this?

From what I wrote above, today, in this post, I think you understand
now where I am coming from.
I don't usually try to write code so it can be easily converted to
another language (I'm not sure how I'd do this!).

I "don't know how to do that" either. But that doesn't stop me from
trying! ;)
If you really are
stuck with a mass of C++ that you need to rewrite in Python or
something (this sounds so bizzare!) can you find tools that
will expand the templates?

Not necessarily so: maybe for the simple ones, but someone can take
(dis)advantage of the lesser-know "capabilities" of templates and that
behavior wouldn't be gotten from a translation (or so I hypothesize).
For instance, one can use templates in such a way as to get a base
class to "inherit" a derived class's behavior. That would be "extreme"
programming indeed, that is highly non-portable to another language. I
think there are lot of things like that in C++ that "carve in stone" a
given program if it is written in C++.
is this your name for people who genuinely disagree with you
on a technical issue?

Not at all. I don't even remember now what I was thinking when I said
that. Maybe that I found it bizarre that you/others don't see the same
issues with, say templates, that I do. Or that I have many times found
people who "come to the defense of their language" if they think it is
"under attack"? It's just a programming language!
 
T

tonytech08

 application_pgp-signature_part
< 1KViewDownload







I'm not sure what you mean by "dead". Templates are a powerful feature
that's unique to C++, and is one of the major features of the language. No
other modern language has anything similar to offer.

Your last statement above seems to be part of what I am saying.
I'm not sure what you mean by "extremist or a propagandist".

See my post I just posted to Nick Keighly.
 
T

tonytech08

JFTR, C++ templates are a special form of compiler macros, which some
other languages (Common Lisp, Scheme) have been offering for a long
time. They're also more of an ad-hoc workaround around the restrictive
C++ type system rather than a feature that has any value itself.


"Restrictive C++ type system": you mean it's statically typed nature?
Does a language have to be one or the other (static vs. dynamic
typing)?
 
T

tonytech08

The way to write effective code is to examine the problems at hand, and
use the right tools for the job.  

That is too broad, IMO. Using all of C++'s features all of the time is
wrought with peril.
It's absurd to say a priori that
you're only going to allow a given language feature to be used a certain
amount.

I have suggested (maybe not in this thread yet) that "using the
minimal subset of features, without being extremist about it" is
preferrable to "using all features in all software".
 Either ban the feature from your code, if you have some real
reason to do so, or let it sink or swim according to its merits.

I tend toward that (banning language features) being the rule rather
than the exception.
 
T

tonytech08

Templates are an essential part of the reason I can be so much more
productive in C++ than in C, along with classes, access control, and
overloading of functions and operators.  I'm sorry that the syntax isn't
prettier, but I'm sick of hearing ignorant people whine.  If you don't
like them, don't use them, but stop trying to tell the rest of us that
we should restrict our code to the dumbed-down subset with which you
feel comfortable.

Ah, "one of the defensive ones". I assure you, that I am not attacking
YOUR language. (It's just a programming language dude!)
 
I

Ian Collins

tonytech08 said:
That is too broad, IMO. Using all of C++'s features all of the time is
wrought with peril.
Where did Jeff say use all of C++'s features all of the time? Knowing
which features best suit the problem at had is the key. Without a
thorough knowledge of those features, one can't determine the best ones
to use.
I have suggested (maybe not in this thread yet) that "using the
minimal subset of features, without being extremist about it" is
preferrable to "using all features in all software".
On one has suggested "using all features in all software".
I tend toward that (banning language features) being the rule rather
than the exception.
How sad.
 
T

tonytech08

And the most common use of templates even today (I'm sure,
although I really don't have any statistics to support it) is to
replace the macros in <generic.h>.

Would dynamic-typing (just for generics, is that possible?) been a
"better" solution?  
 
T

tonytech08

You really hit the spot.
Templates are a much more basic construct than arrays, pointers
and structs. Therefore arrays, pointers and structs should be
introduced as templates.

Arrays? If you view an "array" as a container of objects, then a
template makes obvious sense. If though, you view an "array" as a
contiguous block of memory (C++ remains close to the hardware"), then
array as a template is unappropriate. (Did I grok your implied thought
correctly?)

Pointers: ok.

Structs implemented as templates? How?
 
T

tonytech08

Where did Jeff say use all of C++'s features all of the time?  

Well if he was saying what I have been saying (judicious use), then
why would he write anything? Apparently, he meant C++ is the tool,
whereas I was suggesting that more than just that is required: rules,
policies, standards for using (and even avoiding) the features of the
language.
Knowing
which features best suit the problem at had is the key.  Without a
thorough knowledge of those features, one can't determine the best ones
to use.

Be careful with that though. Techies will be techies and do
"neat" (but very tricky) things with the mechanisms. I think that a
lot of programmers go to ever-increasing usage of "more advanced"
features and never "come back to earth" by questioning or rethinking
such usage.
On one has suggested "using all features in all software".

I still prefer that, even if no one did, though. (And one can extract
implied preferences from what one writes without them being explicitly
literal).

Those who can invent, do. Those who can't... use templates! (hehe). ;)
 
I

Ian Collins

tonytech08 said:
Well if he was saying what I have been saying (judicious use), then
why would he write anything? Apparently, he meant C++ is the tool,
whereas I was suggesting that more than just that is required: rules,
policies, standards for using (and even avoiding) the features of the
language.


Be careful with that though. Techies will be techies and do
"neat" (but very tricky) things with the mechanisms. I think that a
lot of programmers go to ever-increasing usage of "more advanced"
features and never "come back to earth" by questioning or rethinking
such usage.
Then their peers should either restrain them or learn form them.

I once had a member of my staff complain about me using "arcane C++
constructs" so I asked the team whether they wanted to stick with their
current knowledge, or grow it. No one ever make that criticism again.
 
P

Per

To be honest I don't get this banning thing just because some people
can not understand it. It is like saying to mathematicians that they
can't use tensors or physics to stop dealing with string theory. Just
because its too complicated. Sometimes I think the CS field has been
dumbed down just because computers are everywhere and languages like
PHP and Java has produced to many ignorant programmers that does not
really know what a program is or ever think about how their code will
be executed.

I think the approach to this problem would be to require higher
standards from programmers. Seeing that they actually spent some time
reading the more advanced literature there is for the language. Not
just being able to program after reading a "teach yourself X in 21
days" book.

Well what im trying to say is that don't ban things just because you
don't understand it. The entire argument to me sounds more like some
people are whining because they don't understand the more advanced
features. And instead of spending some time and energy (a week or two)
to try and grasp it and expand their knowledge. They just want
everybody else to stop using what they don't understand. This has been
done before and history has often proved this approach to be grossly
wrong and misguided.

Surly when taking your first job as a C++ programmer you wont know all
that there is to know. But thats why there is lead-programmers and
new-programmers. And thats why their salaries differ. If the
new-programmer is observant and willing to learn from a professional
lead-programmer he will soon be better than most of his peers and
score some high paying job. On the other hand if the new-programmers
starts in a company that has a policy of banning all advances
constructs it will be a dead end for him. Never expanding his
horizons.

Then to the question of code portability. I would simply say. Forget
it! It can nearly be done between Verilog and VHDL if you use the
synthesizeable subset and avoid using keywords from the other
language. So if its hard to be done here for a small subset. I see no
good way of solving it for higher level languages.

/Per
 
T

tonytech08

Maybe we should differentiate between different techniques that are
used with template programming:

Indeed! And also decide which (if any) of those advanced "techniques"/
mechanisms to use.
Surely everyone will agree that the
container classes of the STL are plain and simple.

Surely you jest. Conceptually, the concept of "container" is easy to
grok. Wrap that simple concept in obfuscated STL and it's another
matter entirely. Not "plain" by any stretch of the imagination.
Simple? Perhaps relative to "advanced template techniques and
mechanisms" (sounds like a book title (that I would rename: "how not
to use templates"?).

("Overly snowflaked" hierarchy probably applies also for "not
simple".)
It gets a bit more
complicated when you consider traits. Probably the most complicated
thing is the heavy use of SFINAE (like it is done in boost), the CRTP,
or Koenige-Lookup (which is not strictly a template-related problem
but plays a role in template programming). Maybe we should consider
policies like
"Template programming is okay, but no use of SFINAE, CRTP, and other
techniques that are beyond the common skills of our team".

It's not a "skill" thing at all. It's a "practical engineering" thing.
No need to have complexity for complexity's sake or just to hike up
hourly rates. Of what value is software that can only be maintained by
rocket scientists? If it can be done simpler, it should be. If some
"corner case(s)" require(s) highly intricate coding, fine. But it
should not be the norm to use those things unnecessarily just because
one knows of how to use them. Judicious use! (And practical
engineering). Where one, or a team, or a company draws the lines is
subjective. You seem to think that the line is where traits and such
come into the picture. I, OTOH, choose a much earlier place to draw
the line.

How far is C++ away from the problem domain? It can be relatively
guaged by how much time developers spend thinking about the problem
vs. how much time they spend thinking about the language and its
mechanisms and also how long it takes them to become proficient with
the those.
I'm sorry if I couldn't made myself clear (English is not my first
language). I wanted to say that I think that your idea of having a
policy that requires "judicious" use of templates is a good thing.
However, such a policy cannot be made for the whole programming
language but rather for each single project.

I think it is more person/company specific rather than project
specific. After assessing a feature, via use or disuse for years
perhaps, it probably doesn't need to be reanalyzed on per project
basis. Time, knowledge, experience are the keys though to be able to
make the choices. (That is not to say though that given time,
knowledge and experience, ANYONE can do it).
Absolutely. One should always keep it as simple as possible (although
I can understand that programmers who have a certain palette of
techniques tend to use this palette on projects that could have been
solved with "less complicated" tools).

Well that was part of the gist of my original post.
 
T

tonytech08

What kind of a question is that?  

A thought-provoking one? A rhetorical one? One for which the answer is
obvious? Depends on your context probably.
For any X, some programmers
overuse X, others don't.  Without defining "most", your question
doesn't mean anything, and for any concrete definition, it's
probably unanswerable.

One could probably analyze the posts to clc++ and the moderated group
to see what portion of the posts are template-related, for starters.
If one is a consultant that goes from project to project with
different team members, he/she could "have a handle" on that.
My experience is that most application programmers don't use
templates other than those defined in the standard library.

OK. That's one observation. Good. I was thinking though that most
developers create templates and not just use them. Given all the
"press" that templates get (be it literature or newsgroup posts), I
ascertain some degree of enamourment with templates.
 I'd
hardly call that "overuse".

Do you think templates are overused in the std library? And within the
STL even?
Any C++ code will require a ground-up re-implementation if you
want to compile it in another language.  Templates are only a
minor aspect here.

I wouldn't say minor, but yes, there are a number of C++ things that
if used create locked-in code.
A policy which requires "judicious" use of everything is
certainly the way to go.

Apparently, it can't be over-emphasized though.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,608
Members
45,242
Latest member
KendrickKo

Latest Threads

Top