There are still people in the world who don't use Java generics in "ordinary coding." I can believe it with C++ templates, but generics? They aren't even hard to learn/use. Seriously the best features of Java and C++ are respectively generics and templates.
The best way to convince people of things is to make a compelling argument, be non-threatening, and be right.
So long as you are not doing something like using templates as your programming language, parametric polymorphism (generics/templates) is almost certainly good.
1. Avoids code duplication.
This is obvious, but polymorphic code is general code. That is why it is called generics.
2. Supports better static checking.
Without parametric polymorphism you end up writing things like public Object clone()
or public boolean equals(object b)
which are not just abominations, they have types that provide no information about what they do, and invariably end up throwing exceptions all over the place. The alternative to parametric polymorphism is casts all over the place
3. Non parametric polymorphism OOP code is basically unable to handle "binary methods" in a correct way.
You use these often.
4. It is best practice
In Java, use of generics is considered best practice (see Effective Java by Josh Bloch). Major C++ thinkers like Sutter and Alexandrescu also encourage the use of templates to solve a variety of problems.
5. It fits the OO paradigm.
People often don't notice this, but the combination of sub-typing and generics produces a system MUCH more powerful expressive, and object oriented than any system with just one of them.
Consider Scala's mixins. These are a nice feature that lets you pull your objects together from component parts. Generics and templates can simulate some of these benefits. For example, say one of your objects uses a database. Good design would have you abstract out the database access into a separate class. If done right this not only lets you mock your data-store (key to testability), it also means that you can add alternative implementations like that new no-sql database. Here though, you might have a problem, mattering which implementation you use you will get different capabilities of your business object.
Generics to the rescue!
public class Business<S extends Datastore>{
private S store; ...
}
Now you can start statically differentiating your Business
objects based on ability to use database specific features. You still need some runtime checks and casting, but you can start building MUCH better code.
and
6. Normal code doesn't exist.
There are only three things in the programming universe:
- libraries,
- configurations, and
- bad code.
If you don't think about your code like it is a library you are in serious trouble when the requirements for your project change. Architecture is (arguably) the art of designing good APIs.
I find this attitude stunning. After you get used to programming with parametrized types, not using them just makes everything a pain. And, Java and C++ have a bunch of rough spots which they help remedy.
As mentioned in one of the comments from the OP, this is the table that explains how Scala compares for generic programming support. Link to source pdf
Later on, the following summary is provided:
Scala
Using the CONCEPT pattern we can model multi-type concepts, multiple constraints and support retroactive modeling. Furthermore, Scala’s support for implicits means that the drawbacks of the Java and C# solutions in terms of the additional overhead, do not apply to Scala. Thus, Scala scores well in both the implicit argument deduction and the retroactive modeling criteria. Section 6 shows that associated types are supported in Scala through type members and dependent method types, and type members can also be used as type aliases.
As shown in Section 3, Scala supports lexically scoped models. Furthermore type-checking is fully modular. Prioritized overlapping implicits provide some support for concept-based overloading as illustrated by the zipWithN example in Section 6.5. However, overlapping models have to be structured using a subtyping hierarchy, which may not always be desirable. Thus, the score for this feature is only sufficient. Finally, Scala has full support for first-class functions and it also supports equality constraints.
In summary Scala turns out to be a language with excellent support for generic programming features, managing to fare at the same level, or even slightly better, than G (which was specially designed as a language for generic programming in the large) or Haskell (which has been recognized has having very good support for generic programming).
And then in the summary:
Type members and dependent method types add extra power to the language and a combination of the two mechanisms allows associated types to be expressed. In combination with implicits, type members and dependent method types make Scala an language ready for generic programming in the large
Best Answer
It's really widely dependent on the context of the team and the project.
For example, in video games, often the code is the "simplest" possible (and even sometimes too simple) but in large architectures. That's because game developers have a lot of problems to fix and don't want to bother with meta programming (that is a separate very abstract and hard to grasp language inside C++).
At the same time, basic usage of templates are common even in those shops and you can see some template-based optimizations in some very specific functions of some engines.
But in game dev, most people will just avoid any metaprogramming.
Now, on the other extreme side, some really complex or heavy processing applications, that are not common, requires some kind of heavy metaprogramming because of performance and flexibility (at compile time) requirements that are not common. I'm working in one right now.
It's not common but it exists and some niche domains (in some scientific or number-crunching embedded contexts) does require people knowing a lot about metaprogramming or wishing to learn.
In the middle, most people will just use meta-proggramming as "client", not as "designer". Most meta-programming code are bundled in libraries because libraries are tools for code and what is better than a library that can adapt to the custom types you've been working with until now?
Boost (http://boost.org) is a set of libraries, some being made of heavy metaprogramming black magic, and are used in a lot of C++ shops as "STL++", an extension of the STL (and it is). Not every shop does use it for several reason, like compiler compatibility (some boost libraries can make your compiler beg pardon for every time he did hurt your feeling...) and more often because some developers don't like not being able to understand how a tool works inside (try to understand Boost.Spirit...)
Whatever the companies you will work for, some will use this paradigm, some will less or not at all or even forbid them.
There is no consensus because nobody have the same needs, context or team.
But still, obviously, it is used. Maybe ask who use boost on their mailing list to have more real-world examples?