Ben said:
C# generics cannot possibly use any feature of the type argument that is
not
expressed as an interface implementation. Some things, like constructor
parameters, cannot be expressed with interfaces, while others, like simple
arithmetics, aren't on the built-in types. Whatever the reason, if
there's no interface, C# generics can't do it.
Sure. I'm not contesting that templates try to solve problems that generics
do not. I am saying that all of the other problems solved by templates are
better solved by other techniques, most notably explicit code generation.
Moreover, in the overlap between generics and templates, generics are a
clear win because they are so much easier to use.
Just so you understand fully, I challenge you to create a .NET generic for
a moving average (ring buffer of N entries that returns the mean) which
can be instantiated on both double and decimal (the only operations needed
are add
and divide). For bonus points make it work with any UDT that defines
those two operations.
The C++ template is both more straightforward and more efficient.
You have drawn that conclusion before looking at any evidence.
Let's look at some real examples. For trivial cases like the (useless)
static factorial function you can encode your metaprograms in C++
templates:
http://aszt.inf.elte.hu/~gsd/halado_cpp/ch06s04.html
Here is their factorial implementation:
#include <iostream>
template <int N>
struct Factorial
{
enum { value = N * Factorial<N-1>::value };
};
template <>
struct Factorial<1>
{
enum { value = 1 };
};
int main()
{
const int fact5 = Factorial<15>::value;
std::cout << fact5 << endl;
return 0;
}
This is useless because you can just use a lookup function.
Now let's look at something non-trivial, like a high-performance FFT
implementation. The fastest cross-platform FFT implementation is FFTW,
which is C code generated by an OCaml program.
Many C++ advocates have tried to do the same code generation using C++
templates because it would make such a compelling example of templates
actually being good for metaprogramming. However, every single person to
have ever attempted to do this has completely and utterly failed. Dr Dobb's
even published an article on exactly this:
http://www.ddj.com/cpp/199500857
If you look at the OCaml source code of FFTW you will see many non-trivial
symbolic optimizations implemented using pattern matching over variant
types that optimize the generated code in ways that are prohibitively
difficult to implement using C++ templates.
The fact that C++ templates are theoretically capable of doing this because
they are Turing complete is useless because it is practically impossible to
do so because templates are so cumbersome to use for metaprogramming.
Or gain the same capabilities
That is wrong. C++ templates cannot perform specialization based upon
run-time values.
JIT provides both precompilation and run-time compilation. C++ only provides
precompilation.
so the deployed application is lightweight and ready to run immediately.
That is also wrong. Because C++ templates cannot handle run-time values the
only efficient solution is to precompile every conceivable permutation of
inputs. This results in combinatorial code explosion with incredibly
heavy-weight libraries and very slow loading times. C++ is famously bad for
this.
In contrast, JIT compilation can lazily compile code as and when it is
needed. This results in leaner libraries and executables that load faster
and even work cross-platform.
JIT is a disaster if you need fast startup.
If your application requires submillisecond startup times, sure.
More FUD, especially the "easier to debug" part is just outright wrong.
It's like saying that dynamic languages are more productive -- well they
are for small tasks, but for larger ones the benefits of static typing
outweigh the additional effort.
I'm just going to pull rank here. You need to learn some decent languages.
Look at modern statically-typed functional programming languages for a
start.