C++ for Scientists - Technische Universität Dresden
C++ for Scientists - Technische Universität Dresden
C++ for Scientists - Technische Universität Dresden
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
212 CHAPTER 7. EFFECTIVE PROGRAMMING: THE POLYMORPHIC WAY<br />
7.5 From Monomorphic to Polymorphic Behavior<br />
As presented in the last sections, each programming techique (or paradigm) offers different key<br />
benefits regarding effective programming. The imperative programming, the related procedural<br />
paradigm, and the object-related programming are simple and require that all calls to an object<br />
or function have exactly the same typing as the signature. So type checks and type constraints<br />
can be derived directly from the program text. But the effectivness (genericity and applicability)<br />
is greatly reduced <strong>for</strong> real world problems. This is in contrast to polymorphic code that freely<br />
operates only on abstract concept types. Polymorphic behavior enables the use of algorithms<br />
and data structures with several different types. The object-oriented, generic, and functional<br />
programming offer an additional mechanism which delays the actual type instantiation to a<br />
later evaluation point. Compared to the simple monomorphic way, the polymorphic mechanism<br />
is composed of a complex set of inference rules, because there is propagation of type in<strong>for</strong>mation<br />
between the object and function signature and the call signature in both directions.<br />
In object-oriented programming, libraries typically specify that the types supplied to the library<br />
must be derived from a common abstract base class, providing implementa- tions <strong>for</strong> a collection<br />
of pure virtual functions. The library knows only about the abstract base class interface,<br />
but can be extendedto work with new user types derived from the abstract interface. That is,<br />
variability is achieved through differing implementations of the virtual functions in the derived<br />
classes. This is how object-oriented programming supports modules that are closed <strong>for</strong> modification,<br />
yet remain open <strong>for</strong> extension. One strength of this paradigm is its support <strong>for</strong> varying<br />
the types supplied to a module at runtime. Composability of modules is limited, however,<br />
since independently produced modules generally do not agree on common abstract interfaces<br />
from which supplied types must inherit. The paradigm of generic programming, pioneered by<br />
Stepanov, Musser and their collaborators, is based on the principle of decomposing software into<br />
efficient components which make only minimal assumptions about other components, allowing<br />
maximum flexibility in composition. <strong>C++</strong> libraries developed following the generic programming<br />
paradigm typically rely on templates <strong>for</strong> the parametric and ad- hoc polymorphism they<br />
offer. Composability is enhanced as use of a library does not require inheriting from a particular<br />
abstract interface. Interfaces of library components are specified using concept collections of<br />
requirements analogous to, say, Haskell type classes. The key difference to abstract base classes<br />
and inheritance is that a type can be made to satisfy the constraints of a concept retroactively,<br />
independently of the definition of the type. Also, generic programming strives to make algorithms<br />
fully generic, while remaining as efficient as non-generic hand-written algorithms. Such<br />
an approach is not possible when the cost of any customization is a virtual function call.<br />
The strength of polymorphism is that the same piece of code can operate on different types,<br />
even types that are not known at the time the code was written. Such applicability is the<br />
cornerstone of polymorphism because it amplifies the usefulness and reusability of code. If<br />
the types of poymorphism are analysed in more detail, then two different main types can be<br />
observed:<br />
• Ad-hoc polymorphism<br />
• Universal polymorphism<br />
Only the second type, universal polymorphism, is actually important <strong>for</strong> effective programming,<br />
where the first type, ad-hoc polymorphism, is rather convenience.