Frequently Asked Questions:
Relationship with Other Programming Paradigms

Table of contents:

  1. How does Generic Programming relate to Template Metaprogramming?
  2. How does Generic Programming relate to Generative Programming?
  3. How does Generic Programming relate to Object-Oriented Programming?

1. How does Generic Programming relate to Template Metaprogramming?

Template Metaprogramming is a form of Metaprogramming that uses C++ templates to perform computations at compile time. These compile-time computations can be used for anything from type-checking the use of units in programs to the implementation of domain-specific languages embedded in C++.

Generic Programming and Template Metaprogramming are sometimes confused in C++ because the same template system, and in fact the same template tricks, are used to realize both paradigms. However, Template Metaprogramming focuses on the manipulation of programs, whereas Generic Programming focuses on abstracting programs.

In their book C++ Template Metaprogramming, Abrahams and Gurtovoy discuss the Boost Metaprogramming Library (MPL), which applies the principles and practice of Generic Programming to Template Metaprogramming. In essence, MPL is a generic library for template metaprograms.

2. How does Generic Programming relate to Generative Programming?

Generative Programming is a software engineering paradigm based on modeling software families so that, given a particular set of customization requirements, one can automatically generate a specifialized version of a component. Generative Programming and Generic Programming have, at their core, the same notion of modeling families of related abstractions (or components). However, the reason for modeling families in each paradigm is different.

Generative Programming models families of abstractions so that the differences can be encapsulated into customizable features, allowing users to select the set of features they want and generate an efficient, specialized component. In essence, Generative Programming models abstractions to enable the generation of an entire family of abstractions.

Generic Programming, on the other hand, seeks to model families of abstractions so that we can extract the commonalities into concepts and ignore the differences. Generic Programming focuses on the implementation of algorithms that work across families of abstractions.

There is a natural symbiosis between Generative and Generic Programming, evident in generic libraries such as the Matrix Template Library and the Boost Graph Library, which provide Generic algorithms that work for all members of a family of abstractions and Generative data structures that can generate specialized data structures covering many features of these families.

3. How does Generic Programming relate to Object-Oriented Programming?

Object-Oriented Programming is a programming paradigm that views a program as a collective of individual objects that interact by sending messages to each other. Object-Oriented Programming (OOP) is particularly well-suited to modeling problems where the program objects correspond to objects in the real world, and methods correspond to ways in which those objects can be manipulated.

Object-Oriented Programming focuses on building classes that provide a single, rich interface that defines many useful operations consistent with the class's data and intent. Generic Programming instead focuses on minimizing the requirements on and interface to data types, opting instead to permit many different interfaces to the same type as seen through various concepts.

Certain features required by Generic Programming do not map well into mainstream Object-Oriented languages. However, there are often other features of Object-Oriented languages that can be used in their place. Here is a short list of such features:

Concept-based overloading
Object-Oriented Programming permits run-time polymorphism through dynamic dispatching on the receiver of a message, allowing a limited form of concept-based overloading. For instance, if we have a Widget class and two subclasses, Button and TextEntry, we can send the draw() message to a widget and it will be received by draw() in one of the subclasses, which can draw however they please. However, most OO languages do not allow one to overload based on other parameters. This leads to the so-called "binary method problem", where it is not possible to write an isEqual() function for Widgets, Buttons, and TextEntrys that compare two instances of the same actual type without introducing run-time casts. Thus, getting the proper behavior for concept-based overloading in OO languages often requires extra programming effort and run-time dispatching.

Object-Oriented languages with multimethods do permit full concept-based overloading. The following paper describes the relationship between multimethods and concept-based overloading in the context of ConceptC++:

Jaakko Järvi, Douglas Gregor, Jeremiah Willcock, Andrew Lumsdaine, and Jeremy Siek. Algorithm specialization in generic programming: Challenges of constrained generics in C++. In PLDI '06: Proceedings of the ACM SIGPLAN 2006 conference on Programming language design and implementation, June 2006. Note: To appear.

Retroactive modeling
Generic Programming requires the ability to introduce models for types without modifying any of the types involved. In many Object-Oriented languages, the set of classes (or interfaces) that a class inherits, and the set of methods it provides, can only be changed in the definition of the class, making (direct) retroactive modeling impossible.

There are, however, several common Object-Oriented language features that can overcome this limitation. Dynamic Object-Oriented languages that permit modification of classes at run-time (such as Java and Python) do permit retroactive modeling, because one can inject the appropriate methods into an object without modifying the object's class. Mixins are another alternative, which permits the introduction of new superclasses into an object's type. Finally, one can always introduce another level of abstraction via an adapter.

Parametric Polymorphism
Generic Programming is better suited to parametric polymorphism whereas Object-Oriented Programming is based on subtype polymorphism. Parametric polymorphism expressed genericity via type parameterization, constraining the type parameters by concepts (e.g., type T must model Number), whereas subtype polymorphism is based on a subtyping relationship among types (e.g., Rational is a subtype of Number).

The following papers discuss some experiences applying the Generic Programming paradigm within several Object-Oriented languages:

  • Ronald Garcia, Jaakko Järvi, Andrew Lumsdaine, Jeremy Siek, and Jeremiah Willcock. An Extended Comparative Study of Language Support for Generic Programming. Journal of Functional Programming, 2006. Note: Accepted.
  • Jaakko Järvi, Jeremiah Willcock, and Andrew Lumsdaine. Associated Types and Constraint Propagation for Mainstream Object-Oriented Generics. In OOPSLA, October 2005.
  • Ronald Garcia, Jaakko Järvi, Andrew Lumsdaine, Jeremy G. Siek, and Jeremiah Willcock. A Comparative Study of Language Support for Generic Programming. In Proceedings of the 2003 ACM SIGPLAN conference on Object-oriented programming, systems, languages, and applications (OOPSLA'03), October 2003.