Generic Programming

To quote AlexanderStepanov:
Generic programming is a programming method that is based in finding the most abstract representations of efficient algorithms. That is, you start with an algorithm and find the most general set of requirements that allows it to perform and to perform efficiently. The amazing thing is that many different algorithms need the same set of requirements and there are multiple implementations of these requirements.

Generic programming arose out of Stepanov's work with AdaLanguage, and was then moved over to CeePlusPlus to form the StandardTemplateLibrary. It's also been argued that Lisp supported generic programming well before Stepanov's work, in the form of macros. LispMacros (combined with DynamicTyping) allow one to express any code fragment in terms of its barest parameters, allowing a level of abstraction that TemplateMetaprogramming is only beginning to match.

In some ways, generic programming is simply WellFactoredCode. The process of breaking a system into reusable chunks will naturally lead to more abstract and generalized routines. One possible difference is that generic programming seeks to determine the most general representation in isolation, while ReFactoring only generalizes code as the client system requires.

There is some confusion in C++ circles over the definition of GenericProgramming, as the most common use for the STL is to provide parameterized container types. This is an instance of generic programming (it seeks to make code more general), but is more properly termed ParametricPolymorphism. Generic programming also covers parameterization over behavior (HigherOrderFunctions) and the use of interfaces or TypeClasses to specify algorithm requirements.

ConceptCpp introduces GenericProgramming into CeePlusPlus in a more rigorous way and can be used, for example, to enforce requirements when using the STL.
OnceAndOnlyOnce requires generalizing code via ReFactoring in order to simplify the implementation. By this method, many abstractions precipitate out of the code, abstractions that we wouldn't even see otherwise. There's the rub. How do you know what abstractions are useful? And how do you know your abstractions are usefully implemented? Yes, there are standard data structures and algorithms. But anything from a specific problem domain we probably won't understand enough to abstract until we write a few systems, as per the RuleOfThree. (See also ThreeStrikesAndYouRefactor, ThreeStrikesAndYouAutomate, UseBeforeReuse.) Usually, writing the abstraction up-front is PrematureAbstraction.

At the very least, you need to leave the abstraction in flux, even if you know up-front that you'll need an abstraction and know the problem domain. When I write a reusable class-library for a domain in which I am expert, I find I need to tweak the library's ApplicationProgrammingInterface for the first few applications that use it, no matter how thorough my planning was. This is true even if that planning involved analyzing other implementations. Most of the tweaked library code ends up being refactored from the applications themselves.


GenericProgramming was pioneered in other languages prior to STL/templates in C++, but did the name "generic programming" itself come from Stepanov? I can't clearly recall.

Thanks for creating this page; I've been referencing it for a long time. :-) -- DougMerritt
In this day and age, comments about GenericProgramming in Java and C# would doubtless be of interest.

EditText of this page (last edited January 15, 2008) or FindPage with title or text search